The accordion stacks sections in one window: a header per section and the member widgets under it, with a fold that hides the members and pulls everything below up.
Two of the calls checked here are for a caller whose layout is not fixed at build time - one that recomputes every widget's rectangle when its window is resized, or whose sections hold a different number of controls from one moment to the next. n_gui_sectionlist_set_widget_offset() restates where a member sits inside its section, and n_gui_sectionlist_set_widget_hidden() takes one out of the stack without removing it.
#define ALLEGRO_UNSTABLE 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int opt;
while ((opt = getopt(argc, argv, "V:")) != -1) {
switch (opt) {
case 'V':
if (!strcmp("LOG_NULL", optarg))
else if (!strcmp("LOG_NOTICE", optarg))
else if (!strcmp("LOG_INFO", optarg))
else if (!strcmp("LOG_ERR", optarg))
else if (!strcmp("LOG_DEBUG", optarg))
else
return -1;
break;
default:
return -1;
}
}
return 0;
}
static void expect_close(
const char* label,
float got,
float want,
float tol) {
float d = got - want;
if (d < 0) d = -d;
if (d > tol) {
n_log(
LOG_ERR,
"%s: got %.3f, expected %.3f", label, got, want);
}
}
if (!cond) {
}
}
}
}
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()) {
return 1;
}
ALLEGRO_FONT*
font = al_create_builtin_font();
return 1;
}
return 1;
}
4.0f, NULL, NULL);
if (!sl) {
return 1;
}
NULL, NULL);
NULL, NULL);
NULL, NULL);
{
expect_close(
"and widened with it", hdr ? hdr->
w : 0.0f, 300.0f, 0.01f);
expect_close(
"from the new left", hdr ? hdr->
x : 0.0f, 20.0f, 0.01f);
if (hdr) hdr->
h = 145.0f;
expect_close(
"and the header keeps its own height", hdr ? hdr->
h : 0.0f, 20.0f, 0.01f);
}
{
const int flipped[2] = {1, 0};
const int messy[3] = {1, 1, 7};
}
{
int k = 0, refused = 0, added = 0;
added++;
else
refused++;
}
expect_true(
"and refuses the next with -1", refused == 1);
}
return 1;
}
return 0;
}
void process_args(int argc, char **argv)
static void expect_true(const char *label, int cond)
static void expect_close(const char *label, float got, float want, float tol)
static int widget_visible(N_GUI_CTX *gui, int id)
static float widget_y(N_GUI_CTX *gui, int id)
FONT * font
the default 8x8 font, valid after allegro_init()
float x
position x relative to parent window
int header_id
clickable header button widget id
N_GUI_SECTION sections[16]
section storage
float y
position y relative to parent window
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.
void n_gui_sectionlist_set_folded(N_GUI_SECTIONLIST *sl, int section_index, int folded)
set a section's folded state and relayout; does NOT fire on_toggle (for programmatic restore)
void n_gui_sectionlist_set_widget_offset(N_GUI_SECTIONLIST *sl, int section_index, int widget_id, float dy)
state a member's y offset from the section's content top, for a caller that computes its own layout a...
#define N_GUI_ALIGN_LEFT
left aligned text
void n_gui_sectionlist_set_widget_hidden(N_GUI_SECTIONLIST *sl, int section_index, int widget_id, int hidden)
keep a member hidden whatever the fold state, and leave it out of the section's height.
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.
float n_gui_sectionlist_content_height(const N_GUI_SECTIONLIST *sl)
total content height in pixels under the current fold state, for sizing/scrolling the host window
#define N_GUI_SECTION_WIDGETS_MAX
maximum number of member widgets per section.
N_GUI_SECTIONLIST * n_gui_sectionlist_create(N_GUI_CTX *ctx, int window_id, float x, float y0, float width, float header_h, float gap, void(*on_toggle)(int, int, void *), void *user_data)
create an empty section list anchored at (x,y0) in window_id; sections stack downward from y0
void n_gui_sectionlist_set_order(N_GUI_SECTIONLIST *sl, const int *order, int count)
Stack the sections in another order.
N_GUI_WIDGET * n_gui_get_widget(N_GUI_CTX *ctx, int widget_id)
Get a widget pointer by id.
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_sectionlist_set_geometry(N_GUI_SECTIONLIST *sl, float x, float y0, float width, float header_h, float gap)
restate where the list stacks from, how wide its headers are and the two heights it stacks with,...
void n_gui_destroy_ctx(N_GUI_CTX **ctx)
Destroy a GUI context and all its windows/widgets.
int n_gui_sectionlist_add_widget(N_GUI_SECTIONLIST *sl, int section_index, int widget_id)
register an existing widget as a member of a section (captures its current y as the fold offset).
int n_gui_sectionlist_get_count(const N_GUI_SECTIONLIST *sl)
number of sections in the list
int n_gui_sectionlist_add_section(N_GUI_SECTIONLIST *sl, const char *title, float header_y, int folded)
add a section with a header button at header_y (members added next are captured relative to it); retu...
int n_gui_sectionlist_is_section_hidden(const N_GUI_SECTIONLIST *sl, int section_index)
Is a section left out of the stack.
int n_gui_sectionlist_get_order(const N_GUI_SECTIONLIST *sl, int position)
The section stacked at a position.
#define N_GUI_SHAPE_ROUNDED
rounded rectangle shape
int n_gui_sectionlist_is_folded(const N_GUI_SECTIONLIST *sl, int section_index)
query a section's folded state (1 = folded, 0 = expanded)
void n_gui_sectionlist_set_section_hidden(N_GUI_SECTIONLIST *sl, int section_index, int hidden)
Leave a whole section out of the stack, header and members, or put it back.
void n_gui_sectionlist_free(N_GUI_SECTIONLIST **sl)
free the section list (does not destroy the N_GUI widgets or window)
void n_gui_sectionlist_relayout(N_GUI_SECTIONLIST *sl)
re-stack all sections from y0 by current fold state: hide folded members, show and reposition expande...
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.
int n_gui_widget_is_visible(N_GUI_CTX *ctx, int widget_id)
Is a widget currently shown.
The top-level GUI context that holds all windows.
a vertical accordion of foldable sections inside one window; folding hides a section's widgets and re...
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_DEBUG
debug-level messages
#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_NULL
no log output
#define LOG_INFO
informational
Common headers and low-level functions & define.
GUI system: buttons, sliders, text areas, checkboxes, scrollbars, dropdown menus, windows.