A dialog has to be answerable without the mouse. Tab and Shift+Tab reach the buttons as well as the fields; on a focused button Enter or Space presses it and the arrows move to the next or previous button of its window in reading order, going round. Another button bound to Enter does not fire while a button has the keyboard, a mouse press elsewhere takes the keyboard back from a button, and n_gui_focus_takes_key() says which keys a focused button keeps, so an application's own shortcuts can leave them alone.
Whatever has the keyboard, a button, a slider or a list, and whether Tab or a click gave it, is drawn with an outline in the theme's active border colour; the last check draws the window into a memory bitmap and reads it.
#define ALLEGRO_UNSTABLE 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <allegro5/allegro_primitives.h>
if (!ok) {
} else {
}
}
int opt = 0;
while ((opt = getopt(argc, argv, "V:")) != -1) {
if (opt == 'V') {
} else {
return -1;
}
}
return 0;
}
static void on_click(
int widget_id,
void* user_data) {
(void)user_data;
if (widget_id >= 0 && widget_id < 64)
pressed[widget_id]++;
}
ALLEGRO_EVENT ev;
memset(&ev, 0, sizeof(ev));
ev.keyboard.keycode = keycode;
ev.keyboard.modifiers = (unsigned)modifiers;
if (!repeat) {
ev.type = ALLEGRO_EVENT_KEY_DOWN;
}
ev.type = ALLEGRO_EVENT_KEY_CHAR;
ev.keyboard.repeat = repeat ? true : false;
}
int main(
int argc,
char** argv) {
fprintf(stderr, "Usage: %s [-V LOG_LEVEL]\n", argv[0]);
return 2;
}
if (!al_init() || !al_init_font_addon() || !al_init_primitives_addon()) {
return 1;
}
ALLEGRO_FONT*
font = al_create_builtin_font();
return 1;
}
if (field < 0 || go < 0 || other < 0 || cancel < 0 || below < 0 || hidden < 0 || below >= 64) {
return 1;
}
key(
gui, ALLEGRO_KEY_TAB, 0, 0);
key(
gui, ALLEGRO_KEY_TAB, 0, 0);
key(
gui, ALLEGRO_KEY_TAB, ALLEGRO_KEYMOD_SHIFT, 0);
key(
gui, ALLEGRO_KEY_RIGHT, 0, 0);
key(
gui, ALLEGRO_KEY_RIGHT, 0, 0);
key(
gui, ALLEGRO_KEY_DOWN, 0, 0);
key(
gui, ALLEGRO_KEY_RIGHT, 0, 0);
key(
gui, ALLEGRO_KEY_LEFT, 0, 0);
key(
gui, ALLEGRO_KEY_UP, 0, 0);
key(
gui, ALLEGRO_KEY_ENTER, 0, 0);
key(
gui, ALLEGRO_KEY_SPACE, 0, 0);
key(
gui, ALLEGRO_KEY_ENTER, 0, 1);
key(
gui, ALLEGRO_KEY_PAD_ENTER, 0, 0);
key(
gui, ALLEGRO_KEY_ENTER, 0, 0);
{
float x = 0.0f, y = 0.0f, w = 0.0f, h = 0.0f;
ALLEGRO_EVENT ev;
memset(&ev, 0, sizeof(ev));
ev.type = ALLEGRO_EVENT_MOUSE_AXES;
ev.mouse.x = (int)(x + w * 0.5f);
ev.mouse.y = (int)(y + h * 0.5f);
ev.type = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN;
ev.mouse.button = 1;
ev.type = ALLEGRO_EVENT_MOUSE_BUTTON_UP;
}
}
{
ALLEGRO_COLOR mark = al_map_rgb(255, 0, 255);
al_map_rgb(90, 90, 90), al_map_rgb(100, 100, 100), mark,
al_map_rgb(220, 220, 220), al_map_rgb(230, 230, 230),
al_map_rgb(240, 240, 240), 1.0f, 0.0f, 0.0f);
int slider = 0, button = 0;
ALLEGRO_BITMAP* target = NULL;
int old = al_get_new_bitmap_flags();
float x = 0.0f, y = 0.0f, w = 0.0f, h = 0.0f;
unsigned char r = 0, g = 0, b = 0;
slider =
n_gui_add_slider(
gui, win2, 10, 10, 200, 24, 0.0, 100.0, 50.0,
N_GUI_SLIDER_VALUE, NULL, NULL);
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
target = al_create_bitmap(800, 600);
al_set_new_bitmap_flags(old);
if (!target || slider < 0 || button < 0) {
} else {
int s_on = 0, s_off = 0, b_on = 0;
al_set_target_bitmap(target);
al_clear_to_color(al_map_rgb(0, 0, 0));
al_unmap_rgb(al_get_pixel(target, (int)x + 1, (int)(y + h * 0.5f)), &r, &g, &b);
s_off = (r == 255 && g == 0 && b == 255);
al_clear_to_color(al_map_rgb(0, 0, 0));
al_unmap_rgb(al_get_pixel(target, (int)x + 1, (int)(y + h * 0.5f)), &r, &g, &b);
s_on = (r == 255 && g == 0 && b == 255);
al_clear_to_color(al_map_rgb(0, 0, 0));
al_unmap_rgb(al_get_pixel(target, (int)x + 1, (int)(y + h * 0.5f)), &r, &g, &b);
b_on = (r == 255 && g == 0 && b == 255);
al_set_target_bitmap(NULL);
expect_true(
"a slider without the focus has no outline", !s_off);
expect_true(
"a focused slider is outlined in the active border colour", s_on);
}
if (target) al_destroy_bitmap(target);
}
}
void process_args(int argc, char **argv)
static void expect_true(const char *label, int cond)
volatile char key[227]
TRUE while the key is held.
FONT * font
the default 8x8 font, valid after allegro_init()
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_widget_screen_rect(N_GUI_CTX *ctx, int widget_id, float *x, float *y, float *w, float *h)
Where a widget is on screen, rather than inside its window.
void n_gui_raise_window(N_GUI_CTX *ctx, int window_id)
Bring a window to the front (top of draw order).
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.
int n_gui_focus_takes_key(const N_GUI_CTX *ctx, int keycode)
Would the focused widget do something with this particular key.
#define N_GUI_SLIDER_VALUE
slider uses raw start/end values
int n_gui_process_event(N_GUI_CTX *ctx, ALLEGRO_EVENT event)
Process an allegro event through the GUI system.
void n_gui_set_focus(N_GUI_CTX *ctx, int widget_id)
Set keyboard focus to a specific widget.
void n_gui_draw(N_GUI_CTX *ctx)
draw all visible GUI windows and widgets
void n_gui_button_set_keycode(N_GUI_CTX *ctx, int widget_id, int keycode, int modifiers)
Bind a keyboard key with optional modifier requirements to a button.
int n_gui_get_focus(const N_GUI_CTX *ctx)
Which widget has the keyboard, or -1 when none has.
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.
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.
void n_gui_set_default_theme(N_GUI_CTX *ctx, N_GUI_THEME theme)
Set the default theme on a context and sync scrollbar style colors.
void n_gui_set_widget_visible(N_GUI_CTX *ctx, int widget_id, int visible)
Show or hide a widget.
int n_gui_add_textarea(N_GUI_CTX *ctx, int window_id, float x, float y, float w, float h, int multiline, size_t char_limit, void(*on_change)(int, const char *, void *), void *user_data)
Add a text area widget.
#define N_GUI_SHAPE_RECT
rectangle shape (default)
N_GUI_THEME n_gui_make_theme(ALLEGRO_COLOR bg, ALLEGRO_COLOR bg_hover, ALLEGRO_COLOR bg_active, ALLEGRO_COLOR border, ALLEGRO_COLOR border_hover, ALLEGRO_COLOR border_active, ALLEGRO_COLOR text, ALLEGRO_COLOR text_hover, ALLEGRO_COLOR text_active, float border_thickness, float corner_rx, float corner_ry)
Create a custom theme with explicit colours.
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.
The top-level GUI context that holds all windows.
Color theme for a widget.
#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_NOTICE
normal but significant condition
#define LOG_INFO
informational
Common headers and low-level functions & define.
GUI system: buttons, sliders, text areas, checkboxes, scrollbars, dropdown menus, windows.