multiple panels are working

This commit is contained in:
vurtun 2015-03-24 13:08:42 +01:00
parent 5c2ffcae38
commit 1a83fff3e8
5 changed files with 28 additions and 22 deletions

View File

@ -31,5 +31,5 @@ clang: $(BIN)
$(BIN): $(BIN):
@mkdir -p bin @mkdir -p bin
rm -f bin/$(BIN) $(OBJS) rm -f bin/$(BIN) $(OBJS)
$(CC) $(SRC) -D_POSIX_C_SOURCE=200809L $(CFLAGS) -o bin/$(BIN) -lX11 -lGL -lGLU $(CC) $(SRC) -D_POSIX_C_SOURCE=200809L $(CFLAGS) -o bin/$(BIN) -lSDL2 -lGL -lGLU

View File

@ -4,9 +4,8 @@
- Immediate graphical user interface - Immediate graphical user interface
- Suited for embedding into graphical applications - Suited for embedding into graphical applications
- Written in C89 (ANSI C) - Written in C89 (ANSI C)
- Small (~1.5kLOC) - Small (~2.5kLOC)
- Focus on portability and ease of use - Focus on portability and ease of use
- Simplicity over extensive features
- no hidden states or global variables - no hidden states or global variables
- Renderer independent - Renderer independent
- No direct dependencies (not even libc) - No direct dependencies (not even libc)
@ -17,10 +16,14 @@
## Gallery ## Gallery
## Panel
## Font ## Font
## Configuration ## Configuration
## FAQ
## References ## References
# License # License

23
gui.c
View File

@ -15,7 +15,6 @@
#define SATURATE(x) (MAX(0, MIN(1.0f, x))) #define SATURATE(x) (MAX(0, MIN(1.0f, x)))
#define LEN(a) (sizeof(a)/sizeof(a)[0]) #define LEN(a) (sizeof(a)/sizeof(a)[0])
#define ABS(a) (((a) < 0) ? -(a) : (a)) #define ABS(a) (((a) < 0) ? -(a) : (a))
#define UNUSED(a) ((void)(a))
#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) #define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b))
#define INBOX(px, py, x, y, w, h) (BETWEEN(px, x, x+w) && BETWEEN(py, y, y+h)) #define INBOX(px, py, x, y, w, h) (BETWEEN(px, x, x+w) && BETWEEN(py, y, y+h))
#define ALIGNOF(t) ((char*)(&((struct {char c; t _h;}*)0)->_h) - (char*)0) #define ALIGNOF(t) ((char*)(&((struct {char c; t _h;}*)0)->_h) - (char*)0)
@ -758,6 +757,7 @@ gui_widget_image(struct gui_draw_buffer *buffer, const struct gui_image *image)
gui_float image_w; gui_float image_w;
gui_float image_h; gui_float image_h;
if (!buffer || !image) return; if (!buffer || !image) return;
image_x = image->x + image->pad_x; image_x = image->x + image->pad_x;
image_y = image->y + image->pad_y; image_y = image->y + image->pad_y;
image_w = MAX(0, image->w - 2 * image->pad_x); image_w = MAX(0, image->w - 2 * image->pad_x);
@ -1321,6 +1321,7 @@ gui_widget_histo(struct gui_draw_buffer *buffer, const struct gui_histo *histo,
const gui_float item_y = (canvas_y + canvas_h) - item_h; const gui_float item_y = (canvas_y + canvas_h) - item_h;
gui_float item_x = canvas_x + ((gui_float)i * item_w); gui_float item_x = canvas_x + ((gui_float)i * item_w);
item_x = item_x + ((gui_float)i * histo->pad_y); item_x = item_x + ((gui_float)i * histo->pad_y);
if (INBOX(in->mouse_pos.x, in->mouse_pos.y, item_x, item_y, item_w, item_h)) { if (INBOX(in->mouse_pos.x, in->mouse_pos.y, item_x, item_y, item_w, item_h)) {
selected = (in->mouse_down && in->mouse_clicked) ? (gui_int)i: selected; selected = (in->mouse_down && in->mouse_clicked) ? (gui_int)i: selected;
item_color = histo->highlight; item_color = histo->highlight;
@ -1474,6 +1475,7 @@ gui_panel_begin(struct gui_panel *panel, struct gui_draw_buffer *out,
const struct gui_config *config; const struct gui_config *config;
const struct gui_color *header; const struct gui_color *header;
struct gui_rect clip; struct gui_rect clip;
gui_float mouse_x, mouse_y; gui_float mouse_x, mouse_y;
gui_float clicked_x, clicked_y; gui_float clicked_x, clicked_y;
gui_float header_w = w; gui_float header_w = w;
@ -1521,7 +1523,8 @@ gui_panel_begin(struct gui_panel *panel, struct gui_draw_buffer *out,
} else { } else {
clip.x = x; clip.y = y; clip.x = x; clip.y = y;
clip.w = w; clip.h = h; clip.w = w; clip.h = h;
if (panel->flags & GUI_PANEL_SCROLLBAR) clip.h -= config->panel_padding.y; if (panel->flags & GUI_PANEL_SCROLLBAR)
clip.h -= config->panel_padding.y;
panel->header_height = config->panel_padding.y + config->item_padding.y; panel->header_height = config->panel_padding.y + config->item_padding.y;
} }
@ -1535,6 +1538,7 @@ gui_panel_begin(struct gui_panel *panel, struct gui_draw_buffer *out,
header_w -= ((gui_float)text_width + config->panel_padding.x); header_w -= ((gui_float)text_width + config->panel_padding.x);
gui_draw_string(panel->out, panel->font, close_x, close_y, close_w, close_h, gui_draw_string(panel->out, panel->font, close_x, close_y, close_w, close_h,
config->colors[GUI_COLOR_TEXT], X, 1); config->colors[GUI_COLOR_TEXT], X, 1);
if (INBOX(mouse_x, mouse_y, close_x, close_y, close_w, close_h)) { if (INBOX(mouse_x, mouse_y, close_x, close_y, close_w, close_h)) {
if (INBOX(clicked_x, clicked_y, close_x, close_y, close_w, close_h)) if (INBOX(clicked_x, clicked_y, close_x, close_y, close_w, close_h))
ret = !(panel->in->mouse_down && panel->in->mouse_clicked); ret = !(panel->in->mouse_down && panel->in->mouse_clicked);
@ -1555,6 +1559,7 @@ gui_panel_begin(struct gui_panel *panel, struct gui_draw_buffer *out,
min_h = panel->font->height + 2 * config->item_padding.y; min_h = panel->font->height + 2 * config->item_padding.y;
gui_draw_string(panel->out, panel->font, min_x, min_y, min_w, min_h, gui_draw_string(panel->out, panel->font, min_x, min_y, min_w, min_h,
config->colors[GUI_COLOR_TEXT], score, 1); config->colors[GUI_COLOR_TEXT], score, 1);
if (INBOX(mouse_x, mouse_y, min_x, min_y, min_w, min_h)) { if (INBOX(mouse_x, mouse_y, min_x, min_y, min_w, min_h)) {
if (INBOX(clicked_x, clicked_y, min_x, min_y, min_w, min_h)) if (INBOX(clicked_x, clicked_y, min_x, min_y, min_w, min_h))
if (panel->in->mouse_down && panel->in->mouse_clicked) if (panel->in->mouse_down && panel->in->mouse_clicked)
@ -2284,6 +2289,7 @@ gui_panel_end(struct gui_panel *panel)
scroll.target = panel->at_y - panel->y; scroll.target = panel->at_y - panel->y;
if (panel->flags & GUI_PANEL_HEADER) if (panel->flags & GUI_PANEL_HEADER)
scroll.target -= panel->header_height; scroll.target -= panel->header_height;
panel->offset = (gui_float)gui_widget_scroll(panel->out, &scroll, panel->in); panel->offset = (gui_float)gui_widget_scroll(panel->out, &scroll, panel->in);
panel_y = panel->y + panel->height + panel->header_height - config->panel_padding.y; panel_y = panel->y + panel->height + panel->header_height - config->panel_padding.y;
gui_draw_rectf(panel->out, panel->x, panel_y, panel->width, config->panel_padding.y, gui_draw_rectf(panel->out, panel->x, panel_y, panel->width, config->panel_padding.y,
@ -2298,7 +2304,7 @@ gui_panel_end(struct gui_panel *panel)
panel->y + panel->header_height; panel->y + panel->header_height;
gui_draw_line(panel->out, panel->x, padding_y, panel->x + width, gui_draw_line(panel->out, panel->x, padding_y, panel->x + width,
padding_y, config->colors[GUI_COLOR_BORDER]); padding_y, config->colors[GUI_COLOR_BORDER]);
gui_draw_line(panel->out, panel->x, panel->y, panel->x, gui_draw_line(panel->out, panel->x, panel->y, panel->x,
padding_y, config->colors[GUI_COLOR_BORDER]); padding_y, config->colors[GUI_COLOR_BORDER]);
gui_draw_line(panel->out, panel->x + width, panel->y, panel->x + width, gui_draw_line(panel->out, panel->x + width, panel->y, panel->x + width,
@ -2449,7 +2455,6 @@ gui_begin_panel(struct gui_context *ctx, struct gui_panel *panel,
if (!ctx || !panel || !title) if (!ctx || !panel || !title)
return gui_false; return gui_false;
cpanel = CONTAINER_OF(panel, struct gui_context_panel, panel);
global = &ctx->global_buffer; global = &ctx->global_buffer;
out = &ctx->buffer; out = &ctx->buffer;
out->vertex_size = 0; out->vertex_size = 0;
@ -2462,9 +2467,10 @@ gui_begin_panel(struct gui_context *ctx, struct gui_panel *panel,
out->vertex_capacity = global->vertex_capacity - global->vertex_size; out->vertex_capacity = global->vertex_capacity - global->vertex_size;
out->commands = &global->commands[global->command_size]; out->commands = &global->commands[global->command_size];
out->command_capacity = global->command_capacity - global->command_size; out->command_capacity = global->command_capacity - global->command_size;
out->clips = &global->clips[global->clip_size]; out->clips = global->clips;
out->clip_capacity = global->clip_capacity - global->clip_size; out->clip_capacity = global->clip_capacity;
return gui_panel_begin(panel, &ctx->buffer, ctx->input, title, cpanel = CONTAINER_OF(panel, struct gui_context_panel, panel);
return gui_panel_begin(panel, out, ctx->input, title,
cpanel->x, cpanel->y, cpanel->w, cpanel->h, flags); cpanel->x, cpanel->y, cpanel->w, cpanel->h, flags);
} }
@ -2475,13 +2481,12 @@ gui_end_panel(struct gui_context *ctx, struct gui_panel *panel,
struct gui_context_panel *cpanel; struct gui_context_panel *cpanel;
struct gui_draw_buffer *global; struct gui_draw_buffer *global;
if (!ctx || !panel) return; if (!ctx || !panel) return;
cpanel = CONTAINER_OF(panel, struct gui_context_panel, panel); cpanel = CONTAINER_OF(panel, struct gui_context_panel, panel);
gui_panel_end(panel); gui_panel_end(panel);
global = &ctx->global_buffer; global = &ctx->global_buffer;
global->vertex_size += ctx->buffer.vertex_size; global->vertex_size += ctx->buffer.vertex_size;
global->command_size += ctx->buffer.command_size; global->command_size += ctx->buffer.command_size;
global->clip_size += ctx->buffer.clip_size;
gui_output_end(&ctx->buffer, &cpanel->list, status); gui_output_end(&ctx->buffer, &cpanel->list, status);
} }

5
gui.h
View File

@ -453,9 +453,8 @@ struct gui_context;
struct gui_context *gui_new(const struct gui_memory*, const struct gui_input*); struct gui_context *gui_new(const struct gui_memory*, const struct gui_input*);
void gui_begin(struct gui_context*, gui_float width, gui_float height); void gui_begin(struct gui_context*, gui_float width, gui_float height);
void gui_end(struct gui_context*, struct gui_output*, struct gui_memory_status*); void gui_end(struct gui_context*, struct gui_output*, struct gui_memory_status*);
struct gui_panel *gui_panel_new(struct gui_context*, struct gui_panel *gui_panel_new(struct gui_context*, gui_float x, gui_float y, gui_float w,
gui_float x, gui_float y, gui_float w, gui_float h, gui_flags, gui_float h, gui_flags, const struct gui_config* , const struct gui_font*);
const struct gui_config* , const struct gui_font*);
void gui_panel_del(struct gui_context*, struct gui_panel*); void gui_panel_del(struct gui_context*, struct gui_panel*);
gui_bool gui_begin_panel(struct gui_context*, struct gui_panel*, const char *title, gui_flags flags); gui_bool gui_begin_panel(struct gui_context*, struct gui_panel*, const char *title, gui_flags flags);
void gui_end_panel(struct gui_context*, struct gui_panel*, struct gui_memory_status*); void gui_end_panel(struct gui_context*, struct gui_panel*, struct gui_memory_status*);

View File

@ -275,7 +275,6 @@ draw(int width, int height, struct gui_draw_call_list **list, gui_size count)
{ {
gui_size i = 0; gui_size i = 0;
gui_size n = 0; gui_size n = 0;
GLint offset = 0;
const gui_byte *vertexes; const gui_byte *vertexes;
const struct gui_draw_command *cmd; const struct gui_draw_command *cmd;
static const size_t v = sizeof(struct gui_vertex); static const size_t v = sizeof(struct gui_vertex);
@ -304,6 +303,7 @@ draw(int width, int height, struct gui_draw_call_list **list, gui_size count)
glLoadIdentity(); glLoadIdentity();
for (n = 0; n < count; ++n) { for (n = 0; n < count; ++n) {
GLint offset = 0;
vertexes = (const gui_char*)list[n]->vertexes; vertexes = (const gui_char*)list[n]->vertexes;
glVertexPointer(2, GL_FLOAT, (GLsizei)v, (const void*)(vertexes + p)); glVertexPointer(2, GL_FLOAT, (GLsizei)v, (const void*)(vertexes + p));
glTexCoordPointer(2, GL_FLOAT, (GLsizei)v, (const void*)(vertexes + t)); glTexCoordPointer(2, GL_FLOAT, (GLsizei)v, (const void*)(vertexes + t));
@ -350,7 +350,6 @@ main(int argc, char *argv[])
struct gui_memory memory; struct gui_memory memory;
struct gui_input input; struct gui_input input;
struct gui_output output; struct gui_output output;
gui_int id;
/* Window */ /* Window */
UNUSED(argc); UNUSED(argv); UNUSED(argc); UNUSED(argv);
@ -374,15 +373,14 @@ main(int argc, char *argv[])
memory.clip_percentage = 0.01f; memory.clip_percentage = 0.01f;
ctx = gui_new(&memory, &input); ctx = gui_new(&memory, &input);
font = ldfont("mono.sdf", 16);
gui_default_config(&config); gui_default_config(&config);
config.colors[GUI_COLOR_TEXT].r = 255; config.colors[GUI_COLOR_TEXT].r = 255;
config.colors[GUI_COLOR_TEXT].g = 255; config.colors[GUI_COLOR_TEXT].g = 255;
config.colors[GUI_COLOR_TEXT].b = 255; config.colors[GUI_COLOR_TEXT].b = 255;
config.colors[GUI_COLOR_TEXT].a = 255; config.colors[GUI_COLOR_TEXT].a = 255;
font = ldfont("mono.sdf", 16);
panel = gui_panel_new(ctx, 20, 20, 200, 200, 0, &config, font); panel = gui_panel_new(ctx, 20, 20, 200, 200, 0, &config, font);
subpanel = gui_panel_new(ctx, 300, 20, 200, 200, 0, &config, font); subpanel = gui_panel_new(ctx, 250, 20, 200, 200, 0, &config, font);
running = 1; running = 1;
while (running) { while (running) {
@ -409,8 +407,9 @@ main(int argc, char *argv[])
fprintf(stdout, "button pressed!\n"); fprintf(stdout, "button pressed!\n");
gui_end_panel(ctx, panel, NULL); gui_end_panel(ctx, panel, NULL);
gui_begin_panel(ctx, subpanel, "Subdemo", GUI_PANEL_HEADER|GUI_PANEL_SCROLLBAR); gui_begin_panel(ctx, subpanel, "Subdemo",
gui_panel_layout(panel, 30, 1); GUI_PANEL_HEADER|GUI_PANEL_CLOSEABLE|GUI_PANEL_MINIMIZABLE|GUI_PANEL_SCROLLBAR);
gui_panel_layout(subpanel, 30, 1);
if (gui_panel_button_text(subpanel, "button", 6, GUI_BUTTON_SWITCH)) if (gui_panel_button_text(subpanel, "button", 6, GUI_BUTTON_SWITCH))
fprintf(stdout, "subbutton pressed!\n"); fprintf(stdout, "subbutton pressed!\n");
gui_end_panel(ctx, subpanel, NULL); gui_end_panel(ctx, subpanel, NULL);