1use gpui::{
  2    App, Application, Bounds, ColorSpace, Context, Half, Render, Window, WindowOptions, canvas,
  3    div, linear_color_stop, linear_gradient, point, prelude::*, px, size,
  4};
  5
  6struct GradientViewer {
  7    color_space: ColorSpace,
  8}
  9
 10impl GradientViewer {
 11    fn new() -> Self {
 12        Self {
 13            color_space: ColorSpace::default(),
 14        }
 15    }
 16}
 17
 18impl Render for GradientViewer {
 19    fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
 20        let color_space = self.color_space;
 21
 22        div()
 23            .bg(gpui::white())
 24            .size_full()
 25            .p_4()
 26            .flex()
 27            .flex_col()
 28            .gap_3()
 29            .child(
 30                div()
 31                    .flex()
 32                    .gap_2()
 33                    .justify_between()
 34                    .items_center()
 35                    .child("Gradient Examples")
 36                    .child(
 37                        div().flex().gap_2().items_center().child(
 38                            div()
 39                                .id("method")
 40                                .flex()
 41                                .px_3()
 42                                .py_1()
 43                                .text_sm()
 44                                .bg(gpui::black())
 45                                .text_color(gpui::white())
 46                                .child(format!("{}", color_space))
 47                                .active(|this| this.opacity(0.8))
 48                                .on_click(cx.listener(move |this, _, _, cx| {
 49                                    this.color_space = match this.color_space {
 50                                        ColorSpace::Oklab => ColorSpace::Srgb,
 51                                        ColorSpace::Srgb => ColorSpace::Oklab,
 52                                    };
 53                                    cx.notify();
 54                                })),
 55                        ),
 56                    ),
 57            )
 58            .child(
 59                div()
 60                    .flex()
 61                    .flex_1()
 62                    .gap_3()
 63                    .child(
 64                        div()
 65                            .size_full()
 66                            .rounded_xl()
 67                            .flex()
 68                            .items_center()
 69                            .justify_center()
 70                            .bg(gpui::red())
 71                            .text_color(gpui::white())
 72                            .child("Solid Color"),
 73                    )
 74                    .child(
 75                        div()
 76                            .size_full()
 77                            .rounded_xl()
 78                            .flex()
 79                            .items_center()
 80                            .justify_center()
 81                            .bg(gpui::blue())
 82                            .text_color(gpui::white())
 83                            .child("Solid Color"),
 84                    ),
 85            )
 86            .child(
 87                div()
 88                    .flex()
 89                    .flex_1()
 90                    .gap_3()
 91                    .h_24()
 92                    .text_color(gpui::white())
 93                    .child(
 94                        div().flex_1().rounded_xl().bg(linear_gradient(
 95                            45.,
 96                            linear_color_stop(gpui::red(), 0.),
 97                            linear_color_stop(gpui::blue(), 1.),
 98                        )
 99                        .color_space(color_space)),
100                    )
101                    .child(
102                        div().flex_1().rounded_xl().bg(linear_gradient(
103                            135.,
104                            linear_color_stop(gpui::red(), 0.),
105                            linear_color_stop(gpui::green(), 1.),
106                        )
107                        .color_space(color_space)),
108                    )
109                    .child(
110                        div().flex_1().rounded_xl().bg(linear_gradient(
111                            225.,
112                            linear_color_stop(gpui::green(), 0.),
113                            linear_color_stop(gpui::blue(), 1.),
114                        )
115                        .color_space(color_space)),
116                    )
117                    .child(
118                        div().flex_1().rounded_xl().bg(linear_gradient(
119                            315.,
120                            linear_color_stop(gpui::green(), 0.),
121                            linear_color_stop(gpui::yellow(), 1.),
122                        )
123                        .color_space(color_space)),
124                    ),
125            )
126            .child(
127                div()
128                    .flex()
129                    .flex_1()
130                    .gap_3()
131                    .h_24()
132                    .text_color(gpui::white())
133                    .child(
134                        div().flex_1().rounded_xl().bg(linear_gradient(
135                            0.,
136                            linear_color_stop(gpui::red(), 0.),
137                            linear_color_stop(gpui::white(), 1.),
138                        )
139                        .color_space(color_space)),
140                    )
141                    .child(
142                        div().flex_1().rounded_xl().bg(linear_gradient(
143                            90.,
144                            linear_color_stop(gpui::blue(), 0.),
145                            linear_color_stop(gpui::white(), 1.),
146                        )
147                        .color_space(color_space)),
148                    )
149                    .child(
150                        div().flex_1().rounded_xl().bg(linear_gradient(
151                            180.,
152                            linear_color_stop(gpui::green(), 0.),
153                            linear_color_stop(gpui::white(), 1.),
154                        )
155                        .color_space(color_space)),
156                    )
157                    .child(
158                        div().flex_1().rounded_xl().bg(linear_gradient(
159                            360.,
160                            linear_color_stop(gpui::yellow(), 0.),
161                            linear_color_stop(gpui::white(), 1.),
162                        )
163                        .color_space(color_space)),
164                    ),
165            )
166            .child(
167                div().flex_1().rounded_xl().bg(linear_gradient(
168                    0.,
169                    linear_color_stop(gpui::green(), 0.05),
170                    linear_color_stop(gpui::yellow(), 0.95),
171                )
172                .color_space(color_space)),
173            )
174            .child(
175                div().flex_1().rounded_xl().bg(linear_gradient(
176                    90.,
177                    linear_color_stop(gpui::blue(), 0.05),
178                    linear_color_stop(gpui::red(), 0.95),
179                )
180                .color_space(color_space)),
181            )
182            .child(
183                div()
184                    .flex()
185                    .flex_1()
186                    .gap_3()
187                    .child(
188                        div().flex().flex_1().gap_3().child(
189                            div().flex_1().rounded_xl().bg(linear_gradient(
190                                90.,
191                                linear_color_stop(gpui::blue(), 0.5),
192                                linear_color_stop(gpui::red(), 0.5),
193                            )
194                            .color_space(color_space)),
195                        ),
196                    )
197                    .child(
198                        div().flex_1().rounded_xl().bg(linear_gradient(
199                            180.,
200                            linear_color_stop(gpui::green(), 0.),
201                            linear_color_stop(gpui::blue(), 0.5),
202                        )
203                        .color_space(color_space)),
204                    ),
205            )
206            .child(div().h_24().child(canvas(
207                move |_, _, _| {},
208                move |bounds, _, window, _| {
209                    let size = size(bounds.size.width * 0.8, px(80.));
210                    let square_bounds = Bounds {
211                        origin: point(
212                            bounds.size.width.half() - size.width.half(),
213                            bounds.origin.y,
214                        ),
215                        size,
216                    };
217                    let height = square_bounds.size.height;
218                    let horizontal_offset = height;
219                    let vertical_offset = px(30.);
220                    let mut builder = gpui::PathBuilder::fill();
221                    builder.move_to(square_bounds.bottom_left());
222                    builder
223                        .line_to(square_bounds.origin + point(horizontal_offset, vertical_offset));
224                    builder.line_to(
225                        square_bounds.top_right() + point(-horizontal_offset, vertical_offset),
226                    );
227
228                    builder.line_to(square_bounds.bottom_right());
229                    builder.line_to(square_bounds.bottom_left());
230                    let path = builder.build().unwrap();
231                    window.paint_path(
232                        path,
233                        linear_gradient(
234                            180.,
235                            linear_color_stop(gpui::red(), 0.),
236                            linear_color_stop(gpui::blue(), 1.),
237                        )
238                        .color_space(color_space),
239                    );
240                },
241            )))
242    }
243}
244
245fn main() {
246    Application::new().run(|cx: &mut App| {
247        cx.open_window(
248            WindowOptions {
249                focus: true,
250                ..Default::default()
251            },
252            |_, cx| cx.new(|_| GradientViewer::new()),
253        )
254        .unwrap();
255        cx.activate(true);
256    });
257}