]> git.lizzy.rs Git - nothing.git/blob - src/ui/slider.c
Merge pull request #1055 from tsoding/1045
[nothing.git] / src / ui / slider.c
1 #include "system/stacktrace.h"
2 #include "math/rect.h"
3 #include "game/camera.h"
4 #include "./slider.h"
5
6 int slider_render(const Slider *slider, const Camera *camera, Rect boundary)
7 {
8     trace_assert(slider);
9     trace_assert(camera);
10
11     const Color core_color = rgba(0.0f, 0.0f, 0.0f, 1.0f);
12     const float core_height = boundary.h * 0.33f;
13     const Rect core = rect(
14         boundary.x,
15         boundary.y + boundary.h * 0.5f - core_height * 0.5f,
16         boundary.w,
17         core_height);
18     if (camera_fill_rect_screen(camera, core, core_color) < 0) {
19         return -1;
20     }
21
22     const float ratio = slider->value / slider->max_value;
23     const float cursor_width = boundary.w * 0.1f;
24     const Rect cursor = rect(
25         boundary.x + ratio * (boundary.w - cursor_width),
26         boundary.y,
27         cursor_width,
28         boundary.h);
29     const Color cursor_color = rgba(1.0f, 0.0f, 0.0f, 1.0f);
30     if (camera_fill_rect_screen(camera, cursor, cursor_color) < 0) {
31         return -1;
32     }
33
34     return 0;
35 }
36
37 int slider_event(Slider *slider, const SDL_Event *event, Rect boundary, int *selected)
38 {
39     trace_assert(slider);
40     trace_assert(event);
41
42     if (!slider->drag) {
43         switch (event->type) {
44         case SDL_MOUSEBUTTONDOWN: {
45             Point position = vec((float) event->button.x, (float) event->button.y);
46             if (rect_contains_point(boundary, position)) {
47                 slider->drag = 1;
48                 if (selected) {
49                     *selected = 1;
50                 }
51             }
52         } break;
53         }
54     } else {
55         switch (event->type) {
56         case SDL_MOUSEBUTTONUP: {
57             slider->drag = 0;
58             if (selected) {
59                 *selected = 1;
60             }
61         } break;
62
63         case SDL_MOUSEMOTION: {
64             const float x = fminf(fmaxf((float) event->button.x - boundary.x, 0.0f), (float) boundary.w);
65             const float ratio = x / (float) boundary.w;
66             slider->value = ratio * slider->max_value;
67             if (selected) {
68                 *selected = 1;
69             }
70         } break;
71         }
72     }
73
74     return 0;
75 }