gradient.rs

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