Gama C Library
Gama C API Documentation
Loading...
Searching...
No Matches
scale.h
Go to the documentation of this file.
1#pragma once
2
3#include "../animate.h"
4#include "../collision.h"
5#include "../draw.h"
6
7/**
8 * @brief Structure defining the visual theme for a scale (slider) widget.
9 */
10typedef struct {
11 int enabled; /**< Whether the scale is enabled */
12
13 double scale; /**< Overall widget scale */
14
15 gmColor background; /**< Track background color */
16 gmColor border; /**< Track border color */
17
18 struct {
19 double scale; /**< Scale factor when focused/hovered */
20 gmColor border; /**< Border color when focused/hovered */
21 } focussed;
22
23 struct {
24 double scale; /**< Scale factor when active pressed */
25 gmColor border; /**< Border color when active pressed */
26 } active;
27
28 gmColor knob; /**< Knob color */
29 gmColor knob_border; /**< Knob border color */
30
31 double border_width; /**< Track border thickness */
32 double step; /**< Step size for discrete values (0 = allow any value) */
34
35/**
36 * @brief Global scale theme instance with default values.
37 */
38gmwScaleTheme gmwScale = {.enabled = 1,
39 .scale = 1.0,
40
41 .background = 0x3A2A3AE0,
42 .border = 0x7F4F7FFF,
43
44 .focussed = {.scale = 1.03, .border = 0xAA77AAFF},
45 .active = {.scale = 0.97, .border = 0x7F4F7FFF},
46
47 .knob = 0xAA77AAFF,
48 .knob_border = 0x6F3F6FFF,
49
50 .border_width = 0.01,
51 .step = 0.0};
52
53/**
54 * @brief Creates and renders an animated scale (slider) widget that can be
55 * manipulated with the mouse.
56 * @param x The x-coordinate of the scale's center.
57 * @param y The y-coordinate of the scale's center.
58 * @param width The width of the scale track.
59 * @param height The height of the scale track.
60 * @param value Pointer to a double to store the current scale value (0.0
61 * to 1.0).
62 * @param anim Pointer to a double for animated visual position (can be NULL to
63 * use value).
64 * @return 1 if the scale is currently being actively manipulated (mouse down),
65 * 0 otherwise.
66 */
67int gmw_scale_anim(double x, double y, double width, double height,
68 double *value, double *anim) {
69
70 if (value == NULL)
71 return 0;
72 if (*value < 0)
73 *value = 0;
74 if (*value > 1)
75 *value = 1;
76 if (anim != NULL && (*anim > 1 || *anim < 0))
77 *anim = *value;
78
79 int enabled = gmwScale.enabled;
80
81 // Hover test uses full widget size (logical width/height)
82 int hovered = enabled && gm_mouse_in_rect(x, y, width, height);
83 int active = enabled && gm_mouse.down && hovered;
84
85 if (anim == NULL)
86 anim = value;
87 else
88 gm_anim_ease_out_quad(anim, (double)(*value), 0.05);
89
90 // Visual scale / border
91 double scale = 1.0;
92 gmColor border = gmwScale.border;
93 if (active) {
94 scale = gmwScale.active.scale;
95 border = gmwScale.active.border;
96 } else if (hovered) {
97 scale = gmwScale.focussed.scale;
98 border = gmwScale.focussed.border;
99 } else {
100 scale = gmwScale.scale;
101 }
102
103 // Draw sizes (scaled visually)
104 double sw = width * scale;
105 double sh = height * scale;
106
107 // Draw track border
108 gm_draw_rectangle(x, y, sw, sh, border);
109
110 // Track inner size (for knob movement)
111 double track_w = sw - gmwScale.border_width * 2;
112 double track_h = sh - gmwScale.border_width * 2;
113
114 // Draw track
115 gm_draw_rectangle(x, y, track_w, track_h, gmwScale.background);
116
117 // Orientation
118 int horizontal = (width >= height);
119
120 // Handle dragging along logical track (not scaled)
121 if (active) {
122 if (horizontal) {
123 double left = x - width * 0.5 + gmwScale.border_width;
124 double rel =
125 (gm_mouse.position.x - left) / (width - gmwScale.border_width * 2);
126 if (rel < 0.0)
127 rel = 0.0;
128 if (rel > 1.0)
129 rel = 1.0;
130 if (gmwScale.step > 0.0)
131 rel = ((int)(rel / gmwScale.step + 0.5)) * gmwScale.step;
132 *value = rel;
133 } else {
134 double bottom = y - height * 0.5 + gmwScale.border_width;
135 double rel =
136 (gm_mouse.position.y - bottom) / (height - gmwScale.border_width * 2);
137 if (rel < 0.0)
138 rel = 0.0;
139 if (rel > 1.0)
140 rel = 1.0;
141 if (gmwScale.step > 0.0)
142 rel = ((int)(rel / gmwScale.step + 0.5)) * gmwScale.step;
143 *value = rel;
144 }
145 }
146
147 // Draw knob
148 double knob_size = (horizontal ? sh : sw) * 1.5;
149 double knob_x, knob_y;
150
151 if (horizontal) {
152 double left = x - sw * 0.5 + knob_size * 0.5;
153 double right = x + sw * 0.5 - knob_size * 0.5;
154 knob_x = left + (*anim) * (right - left);
155 knob_y = y;
156 } else {
157 double bottom = y - sh * 0.5 + knob_size * 0.5;
158 double top = y + sh * 0.5 - knob_size * 0.5;
159 knob_y = bottom + (*anim) * (top - bottom);
160 knob_x = x;
161 }
162
163 // Draw knob border
164 gm_draw_rectangle(knob_x, knob_y, knob_size + gmwScale.border_width * 2,
165 knob_size + gmwScale.border_width * 2,
166 gmwScale.knob_border);
167
168 // Draw knob
169 gm_draw_rectangle(knob_x, knob_y, knob_size, knob_size, gmwScale.knob);
170
171 return active;
172}
173
174/**
175 * @brief Creates and renders a scale (slider) widget that can be manipulated
176 * with the mouse.
177 * @param x The x-coordinate of the scale's center.
178 * @param y The y-coordinate of the scale's center.
179 * @param width The width of the scale track.
180 * @param height The height of the scale track.
181 * @param value Pointer to a double to store the current scale value (0.0
182 * to 1.0).
183 * @return 1 if the scale is currently being actively manipulated (mouse down),
184 * 0 otherwise.
185 */
186static inline int gmw_scale(double x, double y, double width, double height,
187 double *value) {
188 return gmw_scale_anim(x, y, width, height, value, NULL);
189}
Functions for animating values with various easing functions.
void gm_anim_ease_out_quad(double *value, const double target, double t)
Starts fast and decelerates quadratically to the target. More pronounced than spring.
Definition animate.h:45
int gm_mouse_in_rect(const double x, const double y, const double w, const double h)
Definition collision.h:102
unsigned int gmColor
Type definition for color values in RGBA format.
Definition color.h:8
Functions for drawing shapes, text, and images.
int32_t gm_draw_rectangle(double x, double y, double w, double h, gmColor c)
Draws a rectangle.
Definition draw.h:47
struct _gmMouse gm_mouse
Definition gapi.h:19
int gmw_scale_anim(double x, double y, double width, double height, double *value, double *anim)
Creates and renders an animated scale (slider) widget that can be manipulated with the mouse.
Definition scale.h:67
gmwScaleTheme gmwScale
Global scale theme instance with default values.
Definition scale.h:38
Structure defining the visual theme for a scale (slider) widget.
Definition scale.h:10
gmColor knob_border
Definition scale.h:29
gmColor border
Definition scale.h:16
gmColor background
Definition scale.h:15
double step
Definition scale.h:32
int enabled
Definition scale.h:11
double border_width
Definition scale.h:31
gmColor knob
Definition scale.h:28
double scale
Definition scale.h:13