simple/
simple.rs

1use gpui::{
2    AbsoluteLength, App, Application, Context, CornersRefinement, DefiniteLength, Div, Fill,
3    Length, SharedString, SizeRefinement, StyleRefinement, WeakEntity, Window, WindowOptions, div,
4    prelude::*, px, rgb,
5};
6use gpui_qrcode::QrCode;
7
8struct SimpleExample {
9    inner: QrCode,
10    dot_style: StyleRefinement,
11}
12
13impl SimpleExample {
14    fn new(inner: QrCode) -> Self {
15        Self {
16            inner,
17            dot_style: StyleRefinement {
18                background: Some(Fill::from(gpui::black())),
19                ..Default::default()
20            },
21        }
22    }
23
24    fn render_dot_colors(me: WeakEntity<Self>) -> Div {
25        div()
26            .flex()
27            .gap_2()
28            .child(SharedString::new("Color: "))
29            .children(
30                [
31                    gpui::red(),
32                    gpui::green(),
33                    gpui::blue(),
34                    gpui::yellow(),
35                    gpui::black(),
36                ]
37                .into_iter()
38                .enumerate()
39                .map(|(index, color)| {
40                    let me = me.clone();
41                    div()
42                        .id(SharedString::new(format!("color-{index}")))
43                        .size_8()
44                        .bg(color.clone())
45                        .on_click(move |_ev, _win, cx| {
46                            let _ = me.update(cx, |this, cx| {
47                                this.dot_style.background = Some(Fill::from(color));
48                                cx.notify()
49                            });
50                        })
51                }),
52            )
53    }
54
55    fn render_dot_sizes(me: WeakEntity<Self>) -> Div {
56        div()
57            .flex()
58            .gap_2()
59            .child(SharedString::new("Dot Size: "))
60            .children([0.25f32, 0.5f32, 1f32, 2f32].into_iter().map(|size| {
61                let me = me.clone();
62                div()
63                    .id(SharedString::new(format!("size-{size}")))
64                    .child(SharedString::new(format!("{size}rem")))
65                    .on_click(move |_ev, _win, cx| {
66                        let _ = me.update(cx, |this, cx| {
67                            this.dot_style.size = SizeRefinement {
68                                width: Some(Length::Definite(DefiniteLength::Absolute(
69                                    AbsoluteLength::Rems(gpui::Rems(size)),
70                                ))),
71                                height: Some(Length::Definite(DefiniteLength::Absolute(
72                                    AbsoluteLength::Rems(gpui::Rems(size)),
73                                ))),
74                            };
75                            cx.notify();
76                        });
77                    })
78            }))
79    }
80
81    fn render_pad_sizes(me: WeakEntity<Self>) -> Div {
82        div()
83            .flex()
84            .gap_2()
85            .child(SharedString::new("Padding: "))
86            .children([0.25f32, 0.5f32, 1f32, 2f32].into_iter().map(|size| {
87                let me = me.clone();
88                div()
89                    .id(SharedString::new(format!("padding-size-{size}")))
90                    .child(SharedString::new(format!("{size}rem")))
91                    .on_click(move |_ev, _win, cx| {
92                        let _ = me.update(cx, |this, cx| {
93                            this.inner = this.inner.clone().p(DefiniteLength::Absolute(
94                                AbsoluteLength::Rems(gpui::Rems(size)),
95                            ));
96                            cx.notify();
97                        });
98                    })
99            }))
100    }
101
102    fn render_dot_style(me: WeakEntity<Self>) -> Div {
103        div()
104            .flex()
105            .gap_2()
106            .child(SharedString::new("Dot Style: "))
107            .children(
108                [
109                    StyleRefinement {
110                        corner_radii: CornersRefinement {
111                            top_left: Some(AbsoluteLength::Pixels(px(10.0))),
112                            top_right: Some(AbsoluteLength::Pixels(px(10.0))),
113                            bottom_left: Some(AbsoluteLength::Pixels(px(10.0))),
114                            bottom_right: Some(AbsoluteLength::Pixels(px(10.0))),
115                        },
116                        ..Default::default()
117                    },
118                    StyleRefinement {
119                        corner_radii: CornersRefinement {
120                            top_left: Some(AbsoluteLength::Pixels(px(10.0))),
121                            top_right: Some(AbsoluteLength::Pixels(px(10.0))),
122                            bottom_left: Some(AbsoluteLength::Pixels(px(10.0))),
123                            bottom_right: Some(AbsoluteLength::Pixels(px(0.0))),
124                        },
125                        ..Default::default()
126                    },
127                    StyleRefinement {
128                        corner_radii: CornersRefinement {
129                            top_left: Some(AbsoluteLength::Pixels(px(0.0))),
130                            top_right: Some(AbsoluteLength::Pixels(px(10.0))),
131                            bottom_left: Some(AbsoluteLength::Pixels(px(10.0))),
132                            bottom_right: Some(AbsoluteLength::Pixels(px(10.0))),
133                        },
134                        ..Default::default()
135                    },
136                ]
137                .into_iter()
138                .enumerate()
139                .map(|(index, style)| {
140                    let me = me.clone();
141                    let mut d = div()
142                        .id(SharedString::new(format!("style-{index}")))
143                        .bg(gpui::black())
144                        .size_5();
145
146                    d.style().refine(&style);
147                    d.on_click(move |_ev, _win, cx| {
148                        let _ = me.update(cx, |this, cx| {
149                            this.dot_style.refine(&style);
150                            cx.notify();
151                        });
152                    })
153                }),
154            )
155    }
156
157    fn render_actions(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
158        let me = cx.entity().downgrade();
159        div()
160            .flex()
161            .flex_col()
162            .items_center()
163            .child(SharedString::new("Configuration"))
164            .child(Self::render_dot_colors(me.clone()))
165            .child(Self::render_dot_sizes(me.clone()))
166            .child(Self::render_dot_style(me.clone()))
167            .child(Self::render_pad_sizes(me.clone()))
168        // .child()
169    }
170}
171
172impl Render for SimpleExample {
173    fn render(&mut self, win: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
174        div()
175            .flex()
176            .flex_col()
177            .gap_3()
178            .bg(rgb(0x505050))
179            .size_full()
180            .content_stretch()
181            .justify_center()
182            .items_center()
183            .text_xl()
184            .text_color(rgb(0xffffff))
185            .child(self.inner.clone().refine_dot_style(&self.dot_style))
186            .child(self.render_actions(win, cx))
187    }
188}
189
190fn main() {
191    Application::new().run(|cx: &mut App| {
192        cx.open_window(
193            WindowOptions {
194                ..Default::default()
195            },
196            |_, cx| {
197                let q =
198                    QrCode::try_from(qrcode::QrCode::new("https://hellozoe.app").unwrap()).unwrap();
199                cx.new(|_| SimpleExample::new(q))
200            },
201        )
202        .unwrap();
203    });
204}