34#include <allegro5/allegro_color.h>
35#include <allegro5/allegro_primitives.h>
42#define N_GUI_COLORWHEEL_PI 3.14159265358979f
46#define N_GUI_COLORWHEEL_RINGS 8
48#define N_GUI_COLORWHEEL_SECTORS 48
75 float s = sqrtf(u * u + v * v);
77 float r = 0.0f, g = 0.0f, b = 0.0f;
80 if (h < 0.0f) h += 360.0f;
81 if (s > 1.0f) s = 1.0f;
82 al_color_hsv_to_rgb(h, s, 1.0f, &r, &g, &b);
83 return al_map_rgb_f(r, g, b);
88 float d = sqrtf(*u * *u + *v * *v);
97static void _wheel_geometry(
float x,
float y,
float w,
float h,
float* cx,
float* cy,
float* radius) {
98 *radius = (w < h ? w : h) * 0.5f - 2.0f;
99 if (*radius < 1.0f) *radius = 1.0f;
109 float cx = 0.0f, cy = 0.0f, radius = 0.0f;
110 int ring = 0, sector;
113 if (!widget || !cw)
return;
123 float us[4] = {r0 * cosf(a0), r1 * cosf(a0), r1 * cosf(a1), r0 * cosf(a1)};
124 float vs[4] = {r0 * sinf(a0), r1 * sinf(a0), r1 * sinf(a1), r0 * sinf(a1)};
125 ALLEGRO_VERTEX vtx[6];
126 static const int order[6] = {0, 1, 2, 0, 2, 3};
129 for (k = 0; k < 6; k++) {
132 memset(&vtx[k], 0,
sizeof(vtx[k]));
133 vtx[k].x = cx + us[c] * radius;
134 vtx[k].y = cy - vs[c] * radius;
137 al_draw_prim(vtx, NULL, NULL, 0, 6, ALLEGRO_PRIM_TRIANGLE_LIST);
144 float px = cx + cw->
u * radius, py = cy - cw->
v * radius;
145 float r = radius * 0.07f < 3.0f ? 3.0f : radius * 0.07f;
179 float cx = 0.0f, cy = 0.0f, radius = 0.0f;
181 if (!cw || !wgt || wgt->
w <= 0.0f || wgt->
h <= 0.0f)
return 0;
196 double now = al_get_time();
201 dx * dx + dy * dy <= near_px * near_px) {
215 cw->
u = (ev->
x - cx) / radius;
216 cw->
v = (cy - ev->
y) / radius;
251 if (!block)
return -1;
272 if (!cw || cw->
dragging)
return FALSE;
283 if (!cw)
return FALSE;
static void on_change(const float rgba[4], void *user_data)
the picker's callback
FONT * font
the default 8x8 font, valid after allegro_init()
#define __n_assert(__ptr, __ret)
macro to assert things
float y
pointer y from the widget's top edge; outside 0..h during a DRAG
N_GUI_THEME theme
color theme for this widget
int double_click_radius
how far the pointer may move between the two presses and still count, in pixels.
ALLEGRO_COLOR text_normal
text normal
int type
widget type (N_GUI_TYPE_*)
ALLEGRO_COLOR border_normal
border normal
void * user_data
opaque user pointer handed back to the callback (not owned by n_gui)
int button
1 left, 2 right for DOWN; 1 for UP and DRAG; 0 otherwise
N_GUI_CUSTOM_DRAW draw
paint callback invoked during n_gui_draw (NULL = draw nothing)
void * data
widget-specific data (union via void pointer)
int type
N_GUI_MOUSE_DOWN, _UP, _MOVE, _DRAG or _WHEEL.
ALLEGRO_COLOR bg_normal
background normal
float x
pointer x from the widget's left edge; outside 0..w during a DRAG
double double_click_time
how long after a press a second one still counts as a double click, in seconds.
#define N_GUI_MOUSE_DOWN
custom widget mouse event: a press inside it, button 1 or 2
#define N_GUI_MOUSE_DRAG
custom widget mouse event: the pointer moved with button 1 held after a press in it; reported outside...
void n_gui_custom_set_mouse(N_GUI_CTX *ctx, int widget_id, N_GUI_CUSTOM_MOUSE on_mouse, void *user_data)
give a custom widget mouse input
N_GUI_WIDGET * n_gui_get_widget(N_GUI_CTX *ctx, int widget_id)
Get a widget pointer by id.
#define N_GUI_MOUSE_UP
custom widget mouse event: the release of a button 1 press that began in it, wherever the pointer is ...
#define N_GUI_TYPE_CUSTOM
widget type: owner-draw custom widget (rendering delegated to a callback)
void n_gui_custom_set_destroy(N_GUI_CTX *ctx, int widget_id, void(*destroy)(void *user_data))
hand a custom widget's paint user pointer to the widget
void n_gui_mark_dirty(N_GUI_CTX *ctx)
Mark the GUI as needing a redraw.
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
The top-level GUI context that holds all windows.
Owner-draw custom widget data: a paint callback, an optional mouse callback, and their user pointers.
A mouse event handed to a custom widget, in the widget's own coordinates.
ALLEGRO_COLOR(* N_GUI_COLORWHEEL_COLOUR)(float u, float v, void *user_data)
The colour the disc shows for a point.
ALLEGRO_COLOR n_gui_colorwheel_hue(float u, float v, void *user_data)
The default disc colour: HSV, hue by angle with red to the right and going counter clockwise,...
int n_gui_colorwheel_get(N_GUI_CTX *ctx, int widget_id, float *u, float *v)
Read the point.
int n_gui_colorwheel_new(N_GUI_CTX *ctx, int window_id, float x, float y, float w, float h, N_GUI_COLORWHEEL_CHANGE on_change, void *user_data)
Add a colour wheel, its point in the centre.
void(* N_GUI_COLORWHEEL_CHANGE)(int widget_id, int dragging, void *user_data)
Called when the point moves.
void n_gui_colorwheel_set_colour(N_GUI_CTX *ctx, int widget_id, N_GUI_COLORWHEEL_COLOUR colour, void *user_data)
Paint the disc with the caller's colours.
int n_gui_colorwheel_set(N_GUI_CTX *ctx, int widget_id, float u, float v)
Set the point.
Common headers and low-level functions & define.
int dragging
non-zero while the button is held
static void _wheel_block_destroy(void *user_data)
destroy callback for the block
float press_x
where it was, in the widget
float press_y
where it was, in the widget
void * user_data
handed back to on_change
#define N_GUI_COLORWHEEL_PI
pi, not taken from math.h's M_PI, which strict C does not have
static void _wheel_draw(N_GUI_WIDGET *widget, float x, float y, ALLEGRO_FONT *font, void *user_data)
custom draw callback
_N_GUI_COLORWHEEL * cw
wheel
static int _wheel_mouse(int widget_id, const N_GUI_MOUSE_EVENT *ev, void *user_data)
custom mouse callback
static _N_GUI_COLORWHEEL * _wheel_of(N_GUI_CTX *ctx, int widget_id)
helper: find the wheel behind a widget id, or NULL
double press_time
time of the last left press, al_get_time(), for the double click
_N_GUI_COLORWHEEL_MOUSE mouse
what the mouse callback sees
static void _wheel_clamp(float *u, float *v)
helper: the point kept inside the unit circle
N_GUI_COLORWHEEL_COLOUR colour
the disc's colour, the caller's or the default
static void _wheel_geometry(float x, float y, float w, float h, float *cx, float *cy, float *radius)
helper: the disc's centre and radius in a widget of w by h at x, y
#define N_GUI_COLORWHEEL_SECTORS
rings and sectors the disc is drawn with: enough to look smooth at the sizes a panel gives it
N_GUI_COLORWHEEL_CHANGE on_change
the caller's change callback
#define N_GUI_COLORWHEEL_RINGS
rings and sectors the disc is drawn with: enough to look smooth at the sizes a panel gives it
_N_GUI_COLORWHEEL cw
what the draw callback sees
void * colour_user_data
handed back to colour
a wheel's state, owned by its custom widget
a wheel's state and its mouse callback's context in one allocation, because a custom widget owns one ...
what a wheel's mouse callback needs: the context and the state
A colour wheel for N_GUI: one point in a disc, dragged.