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