17#define ALLEGRO_UNSTABLE 1
24#include <allegro5/allegro_primitives.h>
51 while ((opt = getopt(argc, argv,
"V:")) != -1) {
74 memset(&ev, 0,
sizeof(ev));
75 ev.type = (ALLEGRO_EVENT_TYPE)
type;
78 ev.mouse.dx =
type == ALLEGRO_EVENT_MOUSE_AXES ? 1 : 0;
79 ev.mouse.button = (
unsigned int)button;
85 ALLEGRO_BITMAP* target = NULL;
86 int old = al_get_new_bitmap_flags();
88 al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
89 target = al_create_bitmap(400, 300);
90 al_set_new_bitmap_flags(old);
91 al_set_target_bitmap(target);
92 al_clear_to_color(al_map_rgb(0, 0, 0));
94 al_set_target_bitmap(NULL);
95 al_destroy_bitmap(target);
106int main(
int argc,
char** argv) {
109 float row_h = 0.0f, root_h = 0.0f;
113 fprintf(stderr,
"Usage: %s [-V LOG_LEVEL]\n", argv[0]);
117 if (!al_init() || !al_init_font_addon() || !al_init_primitives_addon()) {
121 ALLEGRO_FONT*
font = al_create_builtin_font();
125 al_destroy_font(
font);
130 row_h = (float)al_get_font_line_height(
font) + 8.0f;
134 if (!popup)
return 1;
144 expect_true(
"entries are made", a > 0 && s > 0 && b > 0 && c > 0 && h > 0 && e > 0 && x > 0 && trailing > 0);
153 expect_true(
"where it was asked", root && root->
x == 10.0f && root->
y == 10.0f);
156 root_h = row_h + 7.0f + row_h + 4.0f;
157 expect_true(
"hidden entries, an empty submenu and a trailing separator take no room", root && root->
h == root_h);
161 feed(
gui, ALLEGRO_EVENT_MOUSE_AXES, 20.0f, 10.0f + row_h + 7.0f + 4.0f, 0);
163 expect_true(
"resting on a submenu opens it", sub != NULL);
164 expect_true(
"to the right, overlapping by two", sub && root && sub->
x == root->
x + root->
w - 2.0f);
165 expect_true(
"its first row level with the row that opened it", sub && sub->
y == 10.0f + row_h + 7.0f);
171 feed(
gui, ALLEGRO_EVENT_MOUSE_AXES, 20.0f, 10.0f + row_h + 3.0f, 0);
173 feed(
gui, ALLEGRO_EVENT_MOUSE_AXES, 20.0f, 10.0f + 4.0f, 0);
177 feed(
gui, ALLEGRO_EVENT_MOUSE_AXES, 20.0f, 10.0f + row_h + 7.0f + 4.0f, 0);
183 if (sub)
feed(
gui, ALLEGRO_EVENT_MOUSE_BUTTON_DOWN, sub->
x + 10.0f, sub->
y + 4.0f, 1);
186 feed(
gui, ALLEGRO_EVENT_MOUSE_BUTTON_UP, 0.0f, 0.0f, 1);
193 expect_true(
"pulled back inside the display", root && root->
x + root->
w <= 400.0f && root->
y + root->
h <= 300.0f);
194 expect_true(
"the heading and the shown entry take their rows", root && root->
h == root_h + row_h + 7.0f + row_h);
197 expect_true(
"on the left when the right has no room", sub && root && sub->
x < root->
x);
205 expect_true(
"free clears the handle", popup == NULL);
209 al_destroy_font(
font);
211 fprintf(stderr,
"ex_gui_popup: %d failure(s)\n",
failures);
214 printf(
"ex_gui_popup: ok\n");
void process_args(int argc, char **argv)
static void expect_true(const char *label, int cond)
static void feed(N_GUI_CTX *gui, int type, int x, int y, int button)
feed one mouse event at display coordinates
static void draw(N_GUI_CTX *gui)
draw the whole context into a memory bitmap
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()
float x
position x on screen
float y
position y on screen
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.
int n_gui_process_event(N_GUI_CTX *ctx, ALLEGRO_EVENT event)
Process an allegro event through the GUI system.
void n_gui_draw(N_GUI_CTX *ctx)
draw all visible GUI windows and widgets
int n_gui_window_is_open(N_GUI_CTX *ctx, int window_id)
Check if a window is currently visible.
N_GUI_WINDOW * n_gui_get_window(N_GUI_CTX *ctx, int window_id)
Get a window pointer by id.
N_GUI_CTX * n_gui_new_ctx(ALLEGRO_FONT *default_font)
Create a new GUI context.
void n_gui_destroy_ctx(N_GUI_CTX **ctx)
Destroy a GUI context and all its windows/widgets.
The top-level GUI context that holds all windows.
A pseudo window that contains widgets.
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_ERR
error conditions
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL ).
#define LOG_INFO
informational
int n_gui_popup_window(const N_GUI_POPUP *popup, int level)
The window of a level, for an application that wants to test it.
void n_gui_popup_set_title(N_GUI_POPUP *popup, const char *text)
Set the heading line over the top level.
void n_gui_popup_close(N_GUI_POPUP *popup)
Close every level without picking anything.
int n_gui_popup_press(N_GUI_POPUP *popup, int entry)
Press the row of an entry, as a click on it would.
int n_gui_popup_open(N_GUI_POPUP *popup, float x, float y)
Open the top level with its corner at a point.
int n_gui_popup_add_item(N_GUI_POPUP *popup, int parent, const char *text, int tag, const char *tip)
Add an item at the end of a level.
int n_gui_popup_add_separator(N_GUI_POPUP *popup, int parent)
Add a separator at the end of a level.
int n_gui_popup_hit(const N_GUI_POPUP *popup, float x, float y)
Is a point on any of its open levels.
#define N_GUI_POPUP_ROOT
the top level, as a parent for n_gui_popup_add_item() and the others
void n_gui_popup_set_shown(N_GUI_POPUP *popup, int entry, int shown)
Show or hide an entry.
int n_gui_popup_add_submenu(N_GUI_POPUP *popup, int parent, const char *text, const char *tip)
Add a submenu at the end of a level.
N_GUI_POPUP * n_gui_popup_new(N_GUI_CTX *ctx, float scale, N_GUI_POPUP_FN on_pick, void *user_data)
Make an empty popup menu in ctx, closed.
int n_gui_popup_is_open(const N_GUI_POPUP *popup)
Is its top level on screen.
void n_gui_popup_set_enabled(N_GUI_POPUP *popup, int entry, int enabled)
Enable or grey out an entry.
void n_gui_popup_free(N_GUI_POPUP **popup)
Close the popup and release the handle.
Common headers and low-level functions & define.
GUI system: buttons, sliders, text areas, checkboxes, scrollbars, dropdown menus, windows.