1use gpui::{
2 Application, Background, Bounds, ColorSpace, Context, Path, PathBuilder, Pixels, Render,
3 TitlebarOptions, Window, WindowBounds, WindowOptions, canvas, div, linear_color_stop,
4 linear_gradient, point, prelude::*, px, rgb, size,
5};
6
7const DEFAULT_WINDOW_WIDTH: Pixels = px(1024.0);
8const DEFAULT_WINDOW_HEIGHT: Pixels = px(768.0);
9
10struct PaintingViewer {
11 default_lines: Vec<(Path<Pixels>, Background)>,
12 _painting: bool,
13}
14
15impl PaintingViewer {
16 fn new(_window: &mut Window, _cx: &mut Context<Self>) -> Self {
17 let mut lines = vec![];
18
19 // draw a lightening bolt ⚡
20 for _ in 0..2000 {
21 // draw a ⭐
22 let mut builder = PathBuilder::fill();
23 builder.move_to(point(px(350.), px(100.)));
24 builder.line_to(point(px(370.), px(160.)));
25 builder.line_to(point(px(430.), px(160.)));
26 builder.line_to(point(px(380.), px(200.)));
27 builder.line_to(point(px(400.), px(260.)));
28 builder.line_to(point(px(350.), px(220.)));
29 builder.line_to(point(px(300.), px(260.)));
30 builder.line_to(point(px(320.), px(200.)));
31 builder.line_to(point(px(270.), px(160.)));
32 builder.line_to(point(px(330.), px(160.)));
33 builder.line_to(point(px(350.), px(100.)));
34 let path = builder.build().unwrap();
35 lines.push((
36 path,
37 linear_gradient(
38 180.,
39 linear_color_stop(rgb(0xFACC15), 0.7),
40 linear_color_stop(rgb(0xD56D0C), 1.),
41 )
42 .color_space(ColorSpace::Oklab),
43 ));
44 }
45
46 Self {
47 default_lines: lines,
48 _painting: false,
49 }
50 }
51}
52
53impl Render for PaintingViewer {
54 fn render(&mut self, window: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
55 window.request_animation_frame();
56 let lines = self.default_lines.clone();
57 div().size_full().child(
58 canvas(
59 move |_, _, _| {},
60 move |_, _, window, _| {
61 for (path, color) in lines {
62 window.paint_path(path, color);
63 }
64 },
65 )
66 .size_full(),
67 )
68 }
69}
70
71fn main() {
72 Application::new().run(|cx| {
73 cx.open_window(
74 WindowOptions {
75 titlebar: Some(TitlebarOptions {
76 title: Some("Vulkan".into()),
77 ..Default::default()
78 }),
79 focus: true,
80 window_bounds: Some(WindowBounds::Windowed(Bounds::centered(
81 None,
82 size(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT),
83 cx,
84 ))),
85 ..Default::default()
86 },
87 |window, cx| cx.new(|cx| PaintingViewer::new(window, cx)),
88 )
89 .unwrap();
90 cx.activate(true);
91 });
92}