Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_gui_color.c
Go to the documentation of this file.
1/*
2 * Nilorea Library
3 * Copyright (C) 2005-2026 Castagnier Mickael
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 */
19
27
28#ifdef HAVE_ALLEGRO
29
30#include <math.h>
31#include <stdio.h>
32#include <string.h>
33
34#include <allegro5/allegro_primitives.h>
35
36#include "nilorea/n_common.h"
37#include "nilorea/n_log.h"
38#include "nilorea/n_gui_color.h"
39
42#define N_GUI_COLOR_W 300.0f
44#define N_GUI_COLOR_ROW 24.0f
46#define N_GUI_COLOR_LABEL 18.0f
48#define N_GUI_COLOR_SWATCH 48.0f
50#define N_GUI_COLOR_PAD 10.0f
52#define N_GUI_COLOR_BTN_W 90.0f
55#define N_GUI_COLOR_CHECK 6.0f
56
58static const char* const _n_gui_color_channels[4] = {"Red", "Green", "Blue", "Alpha"};
59
86
88static float _n_gui_color_clamp(float v) {
89 return v < 0.0f ? 0.0f : (v > 1.0f ? 1.0f : v);
90}
91
92ALLEGRO_MOUSE_CURSOR* n_gui_eyedropper_cursor(float scale) {
93 ALLEGRO_MOUSE_CURSOR* cursor = NULL;
94 ALLEGRO_BITMAP* bitmap = NULL;
95 ALLEGRO_BITMAP* previous = al_get_target_bitmap();
96 ALLEGRO_STATE state;
97 int size = (int)(32.0f * scale + 0.5f);
98 float s = 0.0f, tip_x = 0.0f, tip_y = 0.0f, neck_x = 0.0f, neck_y = 0.0f, bulb_x = 0.0f, bulb_y = 0.0f;
99
100 if (size < 16) size = 16;
101 s = (float)size / 32.0f;
102 al_store_state(&state, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS | ALLEGRO_STATE_BLENDER);
103 /* A memory bitmap: a cursor is copied out of it by the system, and a
104 video one would tie this to whichever display is current. */
105 al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
106 bitmap = al_create_bitmap(size, size);
107 if (!bitmap) {
108 al_restore_state(&state);
109 n_log(LOG_ERR, "eyedropper cursor: could not create a %dx%d bitmap", size, size);
110 return NULL;
111 }
112 al_set_target_bitmap(bitmap);
113 al_clear_to_color(al_map_rgba(0, 0, 0, 0));
114 al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);
115
116 /* Along the diagonal from the tip, bottom left, to the bulb, top right. */
117 tip_x = 1.5f * s;
118 tip_y = (float)size - 1.5f * s;
119 neck_x = 21.0f * s;
120 neck_y = 11.0f * s;
121 bulb_x = 25.5f * s;
122 bulb_y = 6.5f * s;
123 /* The tube: a black outline under a pale fill, the fill narrower, so a
124 black line shows around it on a light photograph and the pale one on
125 a dark photograph. */
126 al_draw_line(tip_x, tip_y, neck_x, neck_y, al_map_rgb(0, 0, 0), 6.0f * s);
127 al_draw_line(tip_x + 1.0f * s, tip_y - 1.0f * s, neck_x, neck_y, al_map_rgb(235, 240, 245), 3.0f * s);
128 /* The collar where the tube meets the bulb, across the diagonal. */
129 al_draw_line(neck_x - 3.5f * s, neck_y - 3.5f * s, neck_x + 3.5f * s, neck_y + 3.5f * s, al_map_rgb(0, 0, 0), 4.0f * s);
130 al_draw_line(neck_x - 2.5f * s, neck_y - 2.5f * s, neck_x + 2.5f * s, neck_y + 2.5f * s, al_map_rgb(235, 240, 245), 1.5f * s);
131 /* The bulb. */
132 al_draw_filled_circle(bulb_x, bulb_y, 6.0f * s, al_map_rgb(255, 255, 255));
133 al_draw_filled_circle(bulb_x, bulb_y, 5.0f * s, al_map_rgb(0, 0, 0));
134 al_draw_filled_circle(bulb_x, bulb_y, 3.5f * s, al_map_rgb(70, 70, 80));
135 /* The tip, one dark pixel where the colour is read. */
136 al_draw_filled_rectangle(0.0f, tip_y - 1.5f * s, 2.0f * s, (float)size, al_map_rgb(0, 0, 0));
137
138 al_set_target_bitmap(previous);
139 al_restore_state(&state);
140 cursor = al_create_mouse_cursor(bitmap, 0, size - 1);
141 al_destroy_bitmap(bitmap);
142 if (!cursor) n_log(LOG_ERR, "eyedropper cursor: Allegro could not make a cursor");
143 return cursor;
144}
145
146void n_gui_draw_color_swatch(float x, float y, float w, float h, const float rgba[4]) {
147 int rows = 0, cols = 0, row = 0;
148
149 if (!rgba || w <= 0.0f || h <= 0.0f) return;
150 /* The checkerboard first, so an alpha below one shows as squares coming
151 * through rather than as a darker colour. Whole squares, the last of each
152 * row and column cut at the swatch's edge. */
153 rows = (int)ceilf(h / N_GUI_COLOR_CHECK);
154 cols = (int)ceilf(w / N_GUI_COLOR_CHECK);
155 for (row = 0; row < rows; row++) {
156 float cy = y + (float)row * N_GUI_COLOR_CHECK;
157 float y2 = cy + N_GUI_COLOR_CHECK < y + h ? cy + N_GUI_COLOR_CHECK : y + h;
158
159 for (int col = 0; col < cols; col++) {
160 float cx = x + (float)col * N_GUI_COLOR_CHECK;
161 float x2 = cx + N_GUI_COLOR_CHECK < x + w ? cx + N_GUI_COLOR_CHECK : x + w;
162 float grey = ((row + col) & 1) ? 0.8f : 0.55f;
163
164 al_draw_filled_rectangle(cx, cy, x2, y2, al_map_rgb_f(grey, grey, grey));
165 }
166 }
167 /* Allegro's default blender takes premultiplied colour. */
168 al_draw_filled_rectangle(x, y, x + w, y + h, al_premul_rgba_f(_n_gui_color_clamp(rgba[0]), _n_gui_color_clamp(rgba[1]), _n_gui_color_clamp(rgba[2]), _n_gui_color_clamp(rgba[3])));
169 al_draw_rectangle(x + 0.5f, y + 0.5f, x + w - 0.5f, y + h - 0.5f, al_map_rgba(0, 0, 0, 160), 1.0f);
170}
171
172void n_gui_color_to_hex(const float rgba[4], char* out, size_t len) {
173 unsigned byte[4] = {0, 0, 0, 0};
174 int c = 0;
175
176 if (!out || len == 0) return;
177 if (!rgba) {
178 out[0] = '\0';
179 return;
180 }
181 for (c = 0; c < 4; c++) byte[c] = (unsigned)lroundf(_n_gui_color_clamp(rgba[c]) * 255.0f);
182 snprintf(out, len, "#%02X%02X%02X%02X", byte[0], byte[1], byte[2], byte[3]);
183}
184
186// cppcheck-suppress constParameterCallback ; callback signature must match N_GUI_CUSTOM_DRAW
187// cppcheck-suppress constParameter ; the same, under the id cppcheck 2.10 uses
188static void _n_gui_color_draw_swatch(N_GUI_WIDGET* widget, float x, float y, ALLEGRO_FONT* font, void* user_data) {
189 const N_GUI_COLOR_PICKER* picker = (const N_GUI_COLOR_PICKER*)user_data;
190
191 (void)font;
192 if (!widget || !picker) return;
193 n_gui_draw_color_swatch(x, y, widget->w, widget->h, picker->rgba);
194}
195
197static void _n_gui_color_set_label(N_GUI_COLOR_PICKER* picker, int channel) {
198 char text[32] = "";
199
200 snprintf(text, sizeof(text), "%s %ld", _n_gui_color_channels[channel], lroundf(picker->rgba[channel] * 255.0f));
201 n_gui_label_set_text(picker->ctx, picker->lbl[channel], text);
202}
203
205static void _n_gui_color_on_slider(int widget_id, double value, void* user_data) {
206 N_GUI_COLOR_PICKER* picker = (N_GUI_COLOR_PICKER*)user_data;
207 int c = 0;
208
209 if (!picker || picker->syncing) return;
210 for (c = 0; c < 4; c++) {
211 if (picker->sl[c] != widget_id) continue;
212 /* in steps of 1/255, so the number on the label is the one kept */
213 picker->rgba[c] = (float)lround(value) / 255.0f;
214 _n_gui_color_set_label(picker, c);
215 if (picker->on_change) picker->on_change(picker->rgba, picker->user_data);
216 n_gui_mark_dirty(picker->ctx);
217 return;
218 }
219}
220
222static void _n_gui_color_on_close_button(int widget_id, void* user_data) {
223 (void)widget_id;
225}
226
229static void _n_gui_color_on_close_window(int window_id, void* user_data) {
230 (void)window_id;
232}
233
234N_GUI_COLOR_PICKER* n_gui_color_picker_new(N_GUI_CTX* ctx, const char* title, float scale) {
235 N_GUI_COLOR_PICKER* picker = NULL;
236 const N_GUI_WINDOW* win = NULL;
237 float pad = 0.0f, row = 0.0f, label = 0.0f, swatch_h = 0.0f, client_w = 0.0f, client_h = 0.0f, inner = 0.0f, y = 0.0f;
238 int c = 0;
239
240 __n_assert(ctx, return NULL);
241 if (scale <= 0.0f) scale = 1.0f;
242 Malloc(picker, N_GUI_COLOR_PICKER, 1);
243 __n_assert(picker, return NULL);
244 picker->ctx = ctx;
245
246 pad = N_GUI_COLOR_PAD * scale;
247 row = N_GUI_COLOR_ROW * scale;
248 label = N_GUI_COLOR_LABEL * scale;
249 swatch_h = N_GUI_COLOR_SWATCH * scale;
250 client_w = N_GUI_COLOR_W * scale;
251 inner = client_w - 2.0f * pad;
252 /* what it is for, the swatch, four labelled sliders, Close */
253 client_h = pad + label + swatch_h + pad + 4.0f * (label + row) + pad + row + pad;
254
255 picker->window = n_gui_add_window(ctx, title ? title : "Colour", 0.0f, 0.0f, client_w, client_h);
256 if (picker->window < 0) {
257 Free(picker);
258 return NULL;
259 }
263 /* n_gui_add_window's height includes the title bar; make room for it */
264 win = n_gui_get_window(ctx, picker->window);
265 if (win) n_gui_window_set_rect(ctx, picker->window, 0.0f, 0.0f, client_w, client_h + win->titlebar_h);
266
267 y = pad;
268 picker->lbl_what = n_gui_add_label(ctx, picker->window, "", pad, y, inner, label, N_GUI_ALIGN_LEFT);
269 y += label;
270 picker->swatch = n_gui_add_custom(ctx, picker->window, pad, y, inner, swatch_h, _n_gui_color_draw_swatch, picker);
271 y += swatch_h + pad;
272 for (c = 0; c < 4; c++) {
273 picker->lbl[c] = n_gui_add_label(ctx, picker->window, _n_gui_color_channels[c], pad, y, inner, label, N_GUI_ALIGN_LEFT);
274 y += label;
275 picker->sl[c] = n_gui_add_slider(ctx, picker->window, pad, y, inner, row, 0.0, 255.0, 255.0, N_GUI_SLIDER_VALUE, _n_gui_color_on_slider, picker);
276 y += row;
277 if (picker->lbl[c] < 0 || picker->sl[c] < 0) break;
278 n_gui_slider_set_step(ctx, picker->sl[c], 1.0);
279 n_gui_slider_set_value_visible(ctx, picker->sl[c], 0);
280 n_gui_set_widget_tooltip(ctx, picker->sl[c], c < 3 ? "How much of this colour, 0 to 255" : "How solid, 0 see-through to 255 opaque");
281 }
282 y += pad;
283 picker->btn_close = n_gui_add_button(ctx, picker->window, "Close", client_w - pad - N_GUI_COLOR_BTN_W * scale, y, N_GUI_COLOR_BTN_W * scale, row, N_GUI_SHAPE_ROUNDED, _n_gui_color_on_close_button, picker);
284 n_gui_close_window(ctx, picker->window);
285 if (c < 4 || picker->lbl_what < 0 || picker->swatch < 0 || picker->btn_close < 0) {
286 n_log(LOG_ERR, "color picker: a widget could not be created");
287 /* the window stays in the context, closed; nothing in it can reach
288 * the freed handle while it is closed except its close callback */
289 n_gui_window_set_close_callback(ctx, picker->window, NULL, NULL);
290 Free(picker);
291 return NULL;
292 }
293 n_gui_set_widget_tooltip(ctx, picker->btn_close, "Every change is already applied; this only closes the window");
294 for (c = 0; c < 4; c++) picker->rgba[c] = 1.0f;
295 return picker;
296}
297
298void n_gui_color_picker_open(N_GUI_COLOR_PICKER* picker, const char* what, const float rgba[4], N_GUI_COLOR_FN on_change, void* user_data) {
299 const N_GUI_WINDOW* win = NULL;
300 float dw = 0.0f, dh = 0.0f;
301 int c = 0;
302
303 __n_assert(picker, return);
304 __n_assert(rgba, return);
305 for (c = 0; c < 4; c++) picker->rgba[c] = _n_gui_color_clamp(rgba[c]);
306 picker->on_change = on_change;
307 picker->user_data = user_data;
308 n_gui_label_set_text(picker->ctx, picker->lbl_what, what ? what : "");
309 /* set from code: the callbacks the sliders fire are not the user's */
310 picker->syncing = 1;
311 for (c = 0; c < 4; c++) {
312 n_gui_slider_set_value(picker->ctx, picker->sl[c], (double)lroundf(picker->rgba[c] * 255.0f));
313 _n_gui_color_set_label(picker, c);
314 }
315 picker->syncing = 0;
316
317 /* centred on the display: the context's size when it has one, else the
318 * current display's, else left where it is */
319 dw = picker->ctx->display_w;
320 dh = picker->ctx->display_h;
321 if ((dw <= 0.0f || dh <= 0.0f) && al_get_current_display()) {
322 dw = (float)al_get_display_width(al_get_current_display());
323 dh = (float)al_get_display_height(al_get_current_display());
324 }
325 win = n_gui_get_window(picker->ctx, picker->window);
326 if (win && dw > 0.0f && dh > 0.0f) {
327 float x = (dw - win->w) * 0.5f;
328 float y = (dh - win->h) * 0.5f;
329
330 n_gui_window_set_rect_axes(picker->ctx, picker->window, x < 0.0f ? 0.0f : x, y < 0.0f ? 0.0f : y, win->w, win->h, 0, 0);
331 }
332 n_gui_open_window(picker->ctx, picker->window);
333 n_gui_raise_window(picker->ctx, picker->window);
334 n_gui_mark_dirty(picker->ctx);
335}
336
338 if (!picker) return;
339 n_gui_close_window(picker->ctx, picker->window);
340 /* nobody is told about a colour nobody is editing any more */
341 picker->on_change = NULL;
342 picker->user_data = NULL;
343 n_gui_mark_dirty(picker->ctx);
344}
345
347 if (!picker) return 0;
348 return n_gui_window_is_open(picker->ctx, picker->window) ? 1 : 0;
349}
350
351int n_gui_color_picker_get(const N_GUI_COLOR_PICKER* picker, float rgba[4]) {
352 int c = 0;
353
354 __n_assert(picker, return FALSE);
355 __n_assert(rgba, return FALSE);
356 for (c = 0; c < 4; c++) rgba[c] = picker->rgba[c];
357 return TRUE;
358}
359
361 return picker ? picker->window : -1;
362}
363
364int n_gui_color_picker_slider(const N_GUI_COLOR_PICKER* picker, int channel) {
365 if (!picker || channel < 0 || channel > 3) return -1;
366 return picker->sl[channel];
367}
368
370 if (!picker || !*picker) return;
372 /* the widgets outlive the handle; none may call back into it */
373 n_gui_window_set_close_callback((*picker)->ctx, (*picker)->window, NULL, NULL);
374 Free(*picker);
375}
376
377#endif /* HAVE_ALLEGRO */
static void on_change(const float rgba[4], void *user_data)
the picker's callback
static ALLEGRO_COLOR grey(float u, float v, void *user_data)
a caller's colour: grey everywhere
static const char * row(N_GUI_TREE *tree, int index)
the text of a visible row, "" past the end
FONT * font
the default 8x8 font, valid after allegro_init()
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
Definition n_common.h:204
#define __n_assert(__ptr, __ret)
macro to assert things
Definition n_common.h:279
#define Free(__ptr)
Free Handler to get errors.
Definition n_common.h:263
float h
height
Definition n_gui.h:1104
float titlebar_h
title bar height
Definition n_gui.h:1320
float w
width
Definition n_gui.h:1102
float w
window width
Definition n_gui.h:1316
float display_w
display/viewport width (set via n_gui_set_display_size)
Definition n_gui.h:1745
float h
window height
Definition n_gui.h:1318
float display_h
display/viewport height
Definition n_gui.h:1747
#define N_GUI_ALIGN_LEFT
left aligned text
Definition n_gui.h:212
void n_gui_raise_window(N_GUI_CTX *ctx, int window_id)
Bring a window to the front (top of draw order).
Definition n_gui.c:2058
int n_gui_add_slider(N_GUI_CTX *ctx, int window_id, float x, float y, float w, float h, double min_val, double max_val, double initial, int mode, void(*on_change)(int, double, void *), void *user_data)
Add a slider widget.
Definition n_gui.c:3106
void n_gui_set_widget_tooltip(N_GUI_CTX *ctx, int widget_id, const char *text)
Set (or clear) the tooltip text of any widget.
Definition n_gui.c:2880
void n_gui_label_set_text(N_GUI_CTX *ctx, int widget_id, const char *text)
set label text content
Definition n_gui.c:6184
void n_gui_window_set_rect(N_GUI_CTX *ctx, int window_id, float x, float y, float w, float h)
Move and resize a window at runtime, reflowing its widgets.
Definition n_gui.c:12196
#define N_GUI_SLIDER_VALUE
slider uses raw start/end values
Definition n_gui.h:178
int n_gui_add_label(N_GUI_CTX *ctx, int window_id, const char *text, float x, float y, float w, float h, int align)
Add a static text label.
Definition n_gui.c:3639
void n_gui_close_window(N_GUI_CTX *ctx, int window_id)
Close (hide) a window.
Definition n_gui.c:1406
void n_gui_window_set_zorder(N_GUI_CTX *ctx, int window_id, int z_mode, int z_value)
Set window z-order mode and value.
Definition n_gui.c:2403
void n_gui_slider_set_step(N_GUI_CTX *ctx, int widget_id, double step)
set slider step increment.
Definition n_gui.c:4014
int n_gui_window_is_open(N_GUI_CTX *ctx, int window_id)
Check if a window is currently visible.
Definition n_gui.c:2506
N_GUI_WINDOW * n_gui_get_window(N_GUI_CTX *ctx, int window_id)
Get a window pointer by id.
Definition n_gui.c:1397
int n_gui_add_window(N_GUI_CTX *ctx, const char *title, float x, float y, float w, float h)
Add a new pseudo-window to the context.
Definition n_gui.c:1277
void n_gui_slider_set_value_visible(N_GUI_CTX *ctx, int widget_id, int visible)
Toggle the built-in value label.
Definition n_gui.c:4156
void n_gui_window_set_close_callback(N_GUI_CTX *ctx, int window_id, void(*on_close)(int, void *), void *user_data)
Set the close button callback for a window.
Definition n_gui.c:1889
void n_gui_open_window(N_GUI_CTX *ctx, int window_id)
Open (show) a window.
Definition n_gui.c:1436
#define N_GUI_WIN_BTN_CLOSE
enable close button on the title bar
Definition n_gui.h:282
#define N_GUI_ZORDER_POPUP
popup/modal dialogs: drawn above EVERYTHING including ALWAYS_ON_TOP windows.
Definition n_gui.h:369
void n_gui_slider_set_value(N_GUI_CTX *ctx, int widget_id, double value)
set the value of a slider widget
Definition n_gui.c:3976
#define N_GUI_SHAPE_ROUNDED
rounded rectangle shape
Definition n_gui.h:172
void n_gui_window_set_flags(N_GUI_CTX *ctx, int window_id, int flags)
Set feature flags on a window.
Definition n_gui.c:2515
void n_gui_mark_dirty(N_GUI_CTX *ctx)
Mark the GUI as needing a redraw.
Definition n_gui.c:1188
void n_gui_window_set_rect_axes(N_GUI_CTX *ctx, int window_id, float x, float y, float w, float h, int scale_x, int scale_y)
n_gui_window_set_rect with per-axis control over the widget reflow.
Definition n_gui.c:12223
int n_gui_add_button(N_GUI_CTX *ctx, int window_id, const char *label, float x, float y, float w, float h, int shape, void(*on_click)(int, void *), void *user_data)
Add a button widget to a window.
Definition n_gui.c:2720
int n_gui_add_custom(N_GUI_CTX *ctx, int window_id, float x, float y, float w, float h, N_GUI_CUSTOM_DRAW draw, void *user_data)
add an owner-draw custom widget; returns the widget id or -1
Definition n_gui.c:5698
The top-level GUI context that holds all windows.
Definition n_gui.h:1669
A single GUI widget.
Definition n_gui.h:1092
A pseudo window that contains widgets.
Definition n_gui.h:1298
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:113
#define LOG_ERR
error conditions
Definition n_log.h:100
int n_gui_color_picker_get(const N_GUI_COLOR_PICKER *picker, float rgba[4])
The colour the picker holds now.
void(* N_GUI_COLOR_FN)(const float rgba[4], void *user_data)
called each time the picked colour changes.
Definition n_gui_color.h:73
void n_gui_color_picker_open(N_GUI_COLOR_PICKER *picker, const char *what, const float rgba[4], N_GUI_COLOR_FN on_change, void *user_data)
Open the picker on a colour, centred on the display.
void n_gui_color_to_hex(const float rgba[4], char *out, size_t len)
Write a colour as #RRGGBBAA, each channel clamped to 0..1 and rounded to the nearest of 255 steps.
int n_gui_color_picker_window(const N_GUI_COLOR_PICKER *picker)
The picker's window id, for a caller that walks its windows or sets their flags.
int n_gui_color_picker_slider(const N_GUI_COLOR_PICKER *picker, int channel)
The slider for one channel, for a caller or a test that drives it.
N_GUI_COLOR_PICKER * n_gui_color_picker_new(N_GUI_CTX *ctx, const char *title, float scale)
Build a colour picker window in ctx, closed.
void n_gui_color_picker_close(N_GUI_COLOR_PICKER *picker)
Close the picker.
void n_gui_draw_color_swatch(float x, float y, float w, float h, const float rgba[4])
Draw a colour as a swatch, over a checkerboard so its alpha shows, with a thin dark border.
void n_gui_color_picker_free(N_GUI_COLOR_PICKER **picker)
Close the picker's window and free the handle.
int n_gui_color_picker_is_open(const N_GUI_COLOR_PICKER *picker)
Whether the picker is open.
ALLEGRO_MOUSE_CURSOR * n_gui_eyedropper_cursor(float scale)
Make a pipette mouse cursor, for a tool that picks a colour from an image.
Definition n_gui_color.c:92
Common headers and low-level functions & define.
static float _n_gui_color_clamp(float v)
helper: clamp a channel to 0..1
Definition n_gui_color.c:88
N_GUI_COLOR_FN on_change
whom to tell
Definition n_gui_color.c:82
float rgba[4]
the colour being edited
Definition n_gui_color.c:77
#define N_GUI_COLOR_SWATCH
height of the large swatch at scale 1
Definition n_gui_color.c:48
static void _n_gui_color_on_slider(int widget_id, double value, void *user_data)
slider callback: one channel moved
int lbl_what
what the colour is for
Definition n_gui_color.c:67
#define N_GUI_COLOR_CHECK
side of one checkerboard square behind a swatch, in pixels.
Definition n_gui_color.c:55
#define N_GUI_COLOR_W
window width at scale 1: wide enough that a slider moved by one step in 255 moves by at least a pixel
Definition n_gui_color.c:42
int btn_close
the Close button
Definition n_gui_color.c:75
static void _n_gui_color_on_close_button(int widget_id, void *user_data)
button callback: Close
void * user_data
handed back to on_change
Definition n_gui_color.c:84
static void _n_gui_color_draw_swatch(N_GUI_WIDGET *widget, float x, float y, ALLEGRO_FONT *font, void *user_data)
custom draw callback of the large swatch
int window
the window
Definition n_gui_color.c:65
static void _n_gui_color_on_close_window(int window_id, void *user_data)
title bar close: the same as the Close button, so the callback is forgotten either way
static const char *const _n_gui_color_channels[4]
the four channels, in the order of the sliders
Definition n_gui_color.c:58
int sl[4]
one slider per channel, 0 to 255
Definition n_gui_color.c:73
int syncing
non-zero while the sliders are set from code, so their callbacks are not taken for the user's
Definition n_gui_color.c:80
#define N_GUI_COLOR_PAD
padding at scale 1
Definition n_gui_color.c:50
#define N_GUI_COLOR_LABEL
height of a label at scale 1
Definition n_gui_color.c:46
int swatch
the large swatch
Definition n_gui_color.c:69
#define N_GUI_COLOR_ROW
height of a slider or button row at scale 1
Definition n_gui_color.c:44
N_GUI_CTX * ctx
the context the widgets live in
Definition n_gui_color.c:63
static void _n_gui_color_set_label(N_GUI_COLOR_PICKER *picker, int channel)
helper: write one channel's label, its name and its value out of 255
#define N_GUI_COLOR_BTN_W
width of the Close button at scale 1
Definition n_gui_color.c:52
int lbl[4]
name and value over each slider
Definition n_gui_color.c:71
a colour picker: the ids of its widgets and the colour being edited
Definition n_gui_color.c:61
A colour picker dialog for N_GUI, and a swatch to show a colour.
Generic log system.