Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ex_gui_custom_mouse.c
Go to the documentation of this file.
1
15
16#define ALLEGRO_UNSTABLE 1
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <unistd.h>
22
23#include "nilorea/n_common.h"
24#include "nilorea/n_log.h"
25#include "nilorea/n_gui.h"
26
27static int log_level = LOG_ERR;
28static int failures = 0;
29
32static int told = 0;
34static int wheel_answer = 1;
36static int destroyed = 0;
37
39static void expect_true(const char* what, int ok) {
40 if (!ok) {
41 n_log(LOG_ERR, "FAIL: %s", what);
42 failures++;
43 } else {
44 n_log(LOG_INFO, "ok: %s", what);
45 }
46}
47
49static int process_args(int argc, char** argv) {
50 int opt = 0;
51
52 while ((opt = getopt(argc, argv, "V:")) != -1) {
53 if (opt == 'V') {
54 log_level = atoi(optarg);
55 } else {
56 return -1;
57 }
58 }
59 return 0;
60}
61
63static int on_mouse(int widget_id, const N_GUI_MOUSE_EVENT* ev, void* user_data) {
64 (void)widget_id;
65 (void)user_data;
66 last = *ev;
67 told++;
68 return ev->type == N_GUI_MOUSE_WHEEL ? wheel_answer : 1;
69}
70
72static void destroy_state(void* state) {
73 destroyed++;
74 free(state);
75}
76
78static int feed(N_GUI_CTX* gui, int type, int x, int y, int button, int dz) {
79 ALLEGRO_EVENT ev;
80
81 memset(&ev, 0, sizeof(ev));
82 ev.type = (ALLEGRO_EVENT_TYPE)type;
83 ev.mouse.x = x;
84 ev.mouse.y = y;
85 ev.mouse.dx = (type == ALLEGRO_EVENT_MOUSE_AXES && dz == 0) ? 1 : 0;
86 ev.mouse.dz = dz;
87 ev.mouse.button = (unsigned int)button;
88 return n_gui_process_event(gui, ev);
89}
90
92static int was(int type, int button, float x, float y) {
93 return last.type == type && last.button == button && last.x == x && last.y == y;
94}
95
96int main(int argc, char** argv) {
97 int before = 0;
98
100 if (process_args(argc, argv) != 0) {
101 fprintf(stderr, "Usage: %s [-V LOG_LEVEL]\n", argv[0]);
102 return 2;
103 }
105 if (!al_init() || !al_init_font_addon()) {
106 n_log(LOG_ERR, "allegro init failed");
107 return 1;
108 }
109 ALLEGRO_FONT* font = al_create_builtin_font();
110 if (!font) return 1;
112 if (!gui) {
113 al_destroy_font(font);
114 return 1;
115 }
116 n_gui_set_display_size(gui, 400.0f, 300.0f);
117 int win = n_gui_add_window(gui, "W", 0.0f, 0.0f, 400.0f, 300.0f);
120
121 int area = n_gui_add_custom(gui, win, 50.0f, 50.0f, 100.0f, 80.0f, NULL, NULL);
122 n_gui_custom_set_mouse(gui, area, on_mouse, NULL);
123
124 feed(gui, ALLEGRO_EVENT_MOUSE_AXES, 60, 70, 0, 0);
125 expect_true("a move over it is a MOVE, in its coordinates", told == 1 && was(N_GUI_MOUSE_MOVE, 0, 10.0f, 20.0f));
126 feed(gui, ALLEGRO_EVENT_MOUSE_BUTTON_DOWN, 60, 70, 1, 0);
127 expect_true("a left press is a DOWN with button 1", was(N_GUI_MOUSE_DOWN, 1, 10.0f, 20.0f));
128 feed(gui, ALLEGRO_EVENT_MOUSE_AXES, 200, 200, 0, 0);
129 expect_true("a drag out of it is still reported, as a DRAG", was(N_GUI_MOUSE_DRAG, 1, 150.0f, 150.0f));
130 /* Allegro reports a move before a release somewhere new, so the pointer
131 is where the last move left it */
132 feed(gui, ALLEGRO_EVENT_MOUSE_AXES, 210, 190, 0, 0);
133 expect_true("so is the next move of the drag", was(N_GUI_MOUSE_DRAG, 1, 160.0f, 140.0f));
134 feed(gui, ALLEGRO_EVENT_MOUSE_BUTTON_UP, 210, 190, 1, 0);
135 expect_true("the release is an UP where the pointer is", was(N_GUI_MOUSE_UP, 1, 160.0f, 140.0f));
136 before = told;
137 feed(gui, ALLEGRO_EVENT_MOUSE_AXES, 220, 220, 0, 0);
138 expect_true("a move elsewhere after it is not reported", told == before);
139
140 feed(gui, ALLEGRO_EVENT_MOUSE_BUTTON_DOWN, 70, 60, 2, 0);
141 expect_true("a right press is a DOWN with button 2", was(N_GUI_MOUSE_DOWN, 2, 20.0f, 10.0f));
142 feed(gui, ALLEGRO_EVENT_MOUSE_BUTTON_UP, 70, 60, 2, 0);
143
144 before = told;
145 expect_true("a wheel it takes is consumed", feed(gui, ALLEGRO_EVENT_MOUSE_AXES, 60, 70, 0, 1) == 1);
146 expect_true("and reported with its steps", told == before + 1 && last.type == N_GUI_MOUSE_WHEEL && last.dz == 1);
147 wheel_answer = 0;
148 before = told;
149 feed(gui, ALLEGRO_EVENT_MOUSE_AXES, 60, 70, 0, -1);
150 expect_true("a wheel it declines is still reported", told == before + 1 && last.dz == -1);
151
152 before = told;
153 feed(gui, ALLEGRO_EVENT_MOUSE_BUTTON_DOWN, 300, 250, 1, 0);
154 feed(gui, ALLEGRO_EVENT_MOUSE_BUTTON_UP, 300, 250, 1, 0);
155 expect_true("a press elsewhere tells it nothing", told == before);
156
157 /* a widget drawn over part of it takes the press there */
158 n_gui_add_button(gui, win, "over", 50.0f, 50.0f, 30.0f, 20.0f, N_GUI_SHAPE_RECT, NULL, NULL);
159 before = told;
160 feed(gui, ALLEGRO_EVENT_MOUSE_BUTTON_DOWN, 55, 55, 1, 0);
161 feed(gui, ALLEGRO_EVENT_MOUSE_BUTTON_UP, 55, 55, 1, 0);
162 expect_true("a press on a widget over it does not reach it", told == before);
163
164 n_gui_custom_set_mouse(gui, area, NULL, NULL);
165 before = told;
166 feed(gui, ALLEGRO_EVENT_MOUSE_BUTTON_DOWN, 100, 100, 1, 0);
167 feed(gui, ALLEGRO_EVENT_MOUSE_BUTTON_UP, 100, 100, 1, 0);
168 expect_true("with the callback taken away it is told nothing", told == before);
169
170 /* ownership */
171 int* state = malloc(sizeof(int));
172 int owner = n_gui_add_custom(gui, win, 200.0f, 10.0f, 20.0f, 20.0f, NULL, state);
174 n_gui_custom_set_destroy(gui, area, NULL);
176 expect_true("owned state is destroyed with the widget, once", destroyed == 1);
177
178 al_destroy_font(font);
179 if (failures) {
180 fprintf(stderr, "ex_gui_custom_mouse: %d failure(s)\n", failures);
181 return 1;
182 }
183 printf("ex_gui_custom_mouse: ok\n");
184 return 0;
185}
void process_args(int argc, char **argv)
static int failures
Definition ex_atlas.c:51
int main(void)
Definition ex_atlas.c:117
static void expect_true(const char *label, int cond)
Definition ex_atlas.c:53
static int log_level
static void feed(N_GUI_CTX *gui, int type, int x, int y, int button)
feed one mouse event at display coordinates
static int told
static int was(int type, int button, float x, float y)
was the last thing told this
static int destroyed
how many times the owned state was destroyed
static int on_mouse(int widget_id, const N_GUI_MOUSE_EVENT *ev, void *user_data)
the widget's mouse callback
static N_GUI_MOUSE_EVENT last
the last event the widget was told of, and how many
static int wheel_answer
what the widget answers to a wheel
static void destroy_state(void *state)
the owned state's destructor
static N_GUI_CTX * gui
static void type(N_GUI_CTX *gui, const char *s)
Type a whole string into whatever has focus.
FONT * font
the default 8x8 font, valid after allegro_init()
int type
N_GUI_MOUSE_DOWN, _UP, _MOVE, _DRAG or _WHEEL.
Definition n_gui.h:1202
void n_gui_set_display_size(N_GUI_CTX *ctx, float w, float h)
set the display (viewport) size so global scrollbars can be computed.
Definition n_gui.c:12348
#define N_GUI_MOUSE_DOWN
custom widget mouse event: a press inside it, button 1 or 2
Definition n_gui.h:1187
#define N_GUI_MOUSE_WHEEL
custom widget mouse event: the wheel turned over it
Definition n_gui.h:1197
int n_gui_process_event(N_GUI_CTX *ctx, ALLEGRO_EVENT event)
Process an allegro event through the GUI system.
Definition n_gui.c:13611
#define N_GUI_MOUSE_DRAG
custom widget mouse event: the pointer moved with button 1 held after a press in it; reported outside...
Definition n_gui.h:1195
#define N_GUI_WIN_FRAMELESS
frameless window: no title bar drawn, drag via window body unless N_GUI_WIN_FIXED_POSITION is also se...
Definition n_gui.h:276
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
Definition n_gui.c:5730
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
N_GUI_CTX * n_gui_new_ctx(ALLEGRO_FONT *default_font)
Create a new GUI context.
Definition n_gui.c:1103
#define N_GUI_MOUSE_MOVE
custom widget mouse event: the pointer moved over it with no button held
Definition n_gui.h:1192
#define N_GUI_MOUSE_UP
custom widget mouse event: the release of a button 1 press that began in it, wherever the pointer is ...
Definition n_gui.h:1190
void n_gui_destroy_ctx(N_GUI_CTX **ctx)
Destroy a GUI context and all its windows/widgets.
Definition n_gui.c:1209
void n_gui_open_window(N_GUI_CTX *ctx, int window_id)
Open (show) a window.
Definition n_gui.c:1436
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
Definition n_gui.c:5745
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
#define N_GUI_SHAPE_RECT
rectangle shape (default)
Definition n_gui.h:170
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 mouse event handed to a custom widget, in the widget's own coordinates.
Definition n_gui.h:1200
#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
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL ).
Definition n_log.c:123
#define LOG_INFO
informational
Definition n_log.h:106
Common headers and low-level functions & define.
GUI system: buttons, sliders, text areas, checkboxes, scrollbars, dropdown menus, windows.
Generic log system.