traffic_lights.rs

 1use std::marker::PhantomData;
 2
 3use crate::prelude::*;
 4use crate::{theme, token, SystemColor};
 5
 6#[derive(Clone, Copy)]
 7enum TrafficLightColor {
 8    Red,
 9    Yellow,
10    Green,
11}
12
13#[derive(Element)]
14struct TrafficLight<S: 'static + Send + Sync> {
15    state_type: PhantomData<S>,
16    color: TrafficLightColor,
17    window_has_focus: bool,
18}
19
20impl<S: 'static + Send + Sync> TrafficLight<S> {
21    fn new(color: TrafficLightColor, window_has_focus: bool) -> Self {
22        Self {
23            state_type: PhantomData,
24            color,
25            window_has_focus,
26        }
27    }
28
29    fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
30        let theme = theme(cx);
31        let system_color = SystemColor::new();
32
33        let fill = match (self.window_has_focus, self.color) {
34            (true, TrafficLightColor::Red) => system_color.mac_os_traffic_light_red,
35            (true, TrafficLightColor::Yellow) => system_color.mac_os_traffic_light_yellow,
36            (true, TrafficLightColor::Green) => system_color.mac_os_traffic_light_green,
37            (false, _) => theme.lowest.base.active.background,
38        };
39
40        div().w_3().h_3().rounded_full().fill(fill)
41    }
42}
43
44#[derive(Element)]
45pub struct TrafficLights<S: 'static + Send + Sync> {
46    state_type: PhantomData<S>,
47    window_has_focus: bool,
48}
49
50impl<S: 'static + Send + Sync> TrafficLights<S> {
51    pub fn new() -> Self {
52        Self {
53            state_type: PhantomData,
54            window_has_focus: true,
55        }
56    }
57
58    pub fn window_has_focus(mut self, window_has_focus: bool) -> Self {
59        self.window_has_focus = window_has_focus;
60        self
61    }
62
63    fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
64        let theme = theme(cx);
65        let token = token();
66
67        div()
68            .flex()
69            .items_center()
70            .gap_2()
71            .child(TrafficLight::new(
72                TrafficLightColor::Red,
73                self.window_has_focus,
74            ))
75            .child(TrafficLight::new(
76                TrafficLightColor::Yellow,
77                self.window_has_focus,
78            ))
79            .child(TrafficLight::new(
80                TrafficLightColor::Green,
81                self.window_has_focus,
82            ))
83    }
84}